\xb5\xbcv\x84\x92\v\xcf\u060f\xe0w\x15\xa1\u02c4\x9c\xa3\xb4P0r\xc0\xc8\tFNj@.\xd2\xdc\xc0\xc2ILk\xe4\xbd\x19\xe8\xde\x14\x88\b\x8b\x0f\u078d\x9b>\xfc>|\xed}W\xe1\xee/^\xe3\x81|,\xfeNy\x97O\u71cb\x0e\x1e\x9dLmj\xf6\xd6\x03L\xf5\n\xdc\x04N\xdco\x9cT\xdbW\x89\xc2\xe8=|'Ck\r\u055d\x02 \x18,\xec\u0093w\u0742\a\xbe\xfd\x05\x89\xc7\u007f\xf4]\xac>\xf9\xc4\x1a\xaf?\x05\x1fr\xb2\xb6\x18\xb9u\xeb\xd7g\xc7<\xfb\xd9\u063c\xf9\u87dey\xe6\xf3\xff\xdb\xdb\xdf\xfe[\u007fCD%\xa1\xfew\u007fw5]~\xf9\xeb\xe4\x99t}O\xc0|?_\x9f\xfc\xe4?\"J\xb0\xbe\xfa\xd5/\x9fu\xd5Uo\xfa\xd4\xddw\u07fdqO\xbf\xb3\xf5\x97\u07ccs\xff\xaf\xff\x86a\xbf\x0f\xe3\xbc\xe6\xc0%~\xdee\xf5\x89\xb4\x8a[;\x977\xf5\aA\x00s\xae\x02\xdek\r\xb8\xe8\u0451zm\xd5\xf4\xdb4\x0e\xf0.i\u6943N\xa9\x94\xb2)\xb3k\x1bY\x97\x96*|\xefT\xc5\u068a\x17\x91q*\xa6mx\x96\x1a\xb4Jk\xc61\xa1\xe6E\xd2\xd4\xfbKc6\xaa\x91i\f\x91\x8a\u058a?\xdf\u059c\xe6@\xa3\xa8D\xaa\x19u\xe21\xc4\u00c6\xc1\x1e\x13\xbc\xe6\u0460Q$\xd26Toz\x131\xf2\xde\f\xc4\x19,\x1b'\x9cp\xc2\xe3\x17\\p\xde'\xae\xbc\xf27\xff\x84\x88\x1eM\u007f\xe7\xc6\x1b\xbf\x87\xe7?\xff\xccg\u0735>\x01\xf3g\xc0\xfa\xad\xdfz\ab(\xed\u55ff\xe6=\xd7_\xff\u03ff\xbfc\u01ce1\xfca\xe5#\xe3\x9e\xf5\x9c\xad\xb8\xf4?}\n\a\x1c\xbd\x19+\xbb\x97|\xb2O\xe9\xa1RM\xbb\xa4\x81p\xcdj=\x8eo\xa3\x99l\x8fj\x80\xa4\xe4\xe0\x13\x80\xb1\rpX\x8b\n\xdf\xe3\x9c\u0358\u007f\xeb\xdaMPZk\x8eH\xc6\xf9c\xd9\x03\xc5Q\xbb\xfd\xda\xff'\u05b9\te\xd5\u49db\xf7W5\x1b\x83\xdb\xe0\x1a\x9b\x95\xb4\x9cL\u0186_\xd1p/\xa0\xea=\xe2F\u056e\x89\x02\x95\xe2}T\xac\xab\xde,\x17\x14)#G\xb0.\xd17%Fk\xe9f\xcb\xf1\x15P\ny\xb7\v3\x1aa\xe7Oo\xc3#?\xf8:\x1e\xf8\xe6ux\xe2\xf6\x9bP\xac.\xb5\x03Sp\xe3,CK 8\xe4Y\a\xe3\xb8\xe3\x8e\xdbu\xce9g\xff\x8f\xdf\xff\xfd\xf7\xfd\x15\x11\u0756\xfe\u03bd\xf7\u0783g?\xfb\xd8g\xecu>\x01\xf3g\xc0\xfa\xc8G\xfe_\xfc\xfa\xaf\xbf1\x80\x89\x1cp\uee7f\xf0\xc9o~\xf3\x9b\x17:\xd7\xeeq\xca\xcc8\xe1\u016f\xc1\x19W\xbe\x17sG\x1e\x8b\xe1\xb0@Q\x14\x10g\xe1b-^*Y\xa8\x01\xec\xd5m\xa9\x84\x03\x88\xba\xe3X\u5e44#\x8f|y\xe4mC&\xd1X\xc5\f\xaa\uedd5{nC\xf9\xa6\xcdk\v\xa72\xc6}\xaf\xc5\xe7\xa0e\x02\xb26\xfe)\xf5\r\xa3\xb4}\xa5\xca\u05e6e\a\x8aI;M@\x8f\x9e.\xdeU\xb0\xb1\xb1H;\xdf.\xc9k]\xbe\xee\u912bT NR\u077f\"Ow\xe9\xa0\x15\x8f\x16\u0205\x93\x92B\x89\u0787\"\xd28uH\xa9\x18W\xd1\x06\x81\t\xac2\xe8N\x0ek,\x1e\xbf\xed{\xb8\xef\x9b\xd7\xe1\xc1\xef\u0740\x9d\xf7\xfc\b\xb6\x18\xb5\xa2Q\x19p\x12\xde\xebLkt{\x1d\x9cx\xc2\t\u063a\xf5\xb9?\xb8\xe0\xfc\xf3\xdf\xf1\xcaW\xbd\xfa\xeb\xe9\xaf\xfd\xdd\xdf]\x8d\xcb/\u007f\xdd3\xfe:\x9f\x80\xf93d\xfd\xf8\u01f7\u2913\x9e\v\x00\xf8\xda\u05fe\xb2\xf5\xfd\xef\u007f\xff\u05ef\xbf\xfe\x86\xb9Vr84\x167m=\a[^q%\x8e8\xfbE\xe8\x1e\xf8,\x18\xe3P\f\ap\u0468\xab\x85w\x8d\x00V\xafM\xa5\xf4\xb3\x8eG\xf8\xf8;&\xe1\xc7K\x87\xbb\xa4t\x96\x96t\x84\xb1\xea\xbcm\x80\xa6\r\xe9Z\x88\xf65\xbdRP\xc9\xef\x9a\x00\xdb\x1c\xe0\u065b>[jS\xad\xd5\xf3\xad\x03yx\xf6m\x8a\x97\xb0\xf9U:q\n\x95\xaf\xff\xa6kP[Q:\x18+\xed\u0606\xb4e\xe5N5\xc0\x8f\xf7i\xa4\xd2RF\x8f\x1eA4.KN\x19\xa8d\x89\x11\xc0\xe3\xaeKD\xe0,\x83\xce;p\xd6b\xdb\x1d?\xc4\xdd_\xfe\x14\xee\xff\xe6ux\xf2\xbe\xdb\xd1\xf4\a\x8a\x0f\xa0\x04p?\xf5C\x9dN\x8e\x99\xe9\x19l\u06b4\t\xcf{\xde)\v'\x9ex\u009f\xfc\xd6o\xbd\xf3CD\xb4\v\x00>\xfe\xf1\x8f\xf1k_\xfbknreO\xc0\xfc\x19\xb9n\xba\xe9\xfbt\xdai\xa7\v\x00|\xe2\x13\xff\xf0\x92\xff\xfc\x9f\xff\xeb5\xdf\xfe\xf6wf\xdb>\x16\x14F\xfa\xa7\xd6o\xc0\xc6\u7783\x13^\xf6F\x1cv\xea\xb9PS3\xb0\xc6\xc1\fVk\x8d\xae\x8a\xb2\x90\x06\x8f^\x81I\x12(_\x1bXI\xc1\xbcf\xb0DU\xd5O\r\xad\xf2ZMKip\xed\xcd\x1fn\xca'E\x9a\xbe1\x82*\xbb\xa1\x82cn\xb1*H=l\u02a1\x9e\xf0}\xa6\xf1\xfec\x94]J\xa8d\u02f0\x86\xe4a\xa6\x1b\x9dC}X\b\t\xe0\u01e0\xb44\x06/Fw\xc6\u7903\xc3c\xf4\b72\xde\xe5\xb0R\xdf\\R\x8a\xab&-M^\u0426\xb5B\xa9Ya\x8dNo\n\"\x82'\xef\xbb\x1dw|\xe1\xbf\xe3\xbeo~\x1e\xbb\x1f\xb8\x13f4h1\x81!\x1f$\xce\f\x11'\xe2\x84\xe6\xe6f1;;\x83C\x0e9\x14g\x9f}\xe6\u03a3\x8f>\xfa/^x\xf1%\u007f{\u0496\x93\x1e\x04\x80W\xbe\xf2\x15\xea\x13\x9f\xf8\x94\xdd_\u0331&`>Y\xff\xcb\xeb\xaf\xfe\xea/\xf8Moz\x8b\x03\x80\xab\xaf\xfe\u0605\x1f\xf9\xc8G\xae\xf9\xcew\xbe\xbba4\x1a\x19\xa5\x94\xb2\u05b5\xea3f\x0f9\x1c\x87\x9dz.\x8e\xb9\xe8Wp\xe8\xd6s\xa0{3(\x06\xabp\x81\x96i~\xa4\u04a37S\x134+d\xa5\x06\xa7]w\xf1\xab6\x95\xa6\xba\xa5\xc9\x17\xd7\x14\x19M\xab\xdb=\xad\x06h1\x118\xdcge\x0e\x15\x81\x8f\xcaA\xa7X\xc4:Y;u'\x1d\xb2\xa9\x01:\u0579\xf9\x96t\xb9\xbd6C}\x90\x03\x95\x9bb\xc6\x04\x15\xc0\x19\xa5\xc5,\xd5\f\u04cc\xabd\xa4\xae\xda&\x91\xe4\x8d\xd4\r\xba\xa4\x02o$\x9b\x05\xa5\xd2$q0\u0387C\xe4\xdd\x0e\x96\x1f\u007f\bw\xdf\xf0I\xfc\xf8\u068fc\xe7Oo\x83\xb4T\xe2Q\x99\xa2\x98\xc59g\x8c)p\xd0A\af\x1b6\x1c\x8c\x83\x0f>x\xfb\x19g<\xff\xd6\xd3N;\xf5\u00ff\xf2+\xbfz\x1d\x11-\xc7\u07fb\xfa\xea\x8f\xd2\xeb^\xf7z\x99\\\xc5\x130\x9f\xac\xb0>\xf4\xa1\xbf\xe4\xdf\xfc\xcd7;\x00\xf8\xf4\xa7?y\xc1\xd5W_\xfd\x0f\xdf\xfa\u05b77\xec\xdc\xf9$\x98\u0649\b\xa7>.13\x93\x94\xc6\xf4\xc1\x1b\xb1\xf9\u0717\xe1\x84\u02ee\xc0\xfag\x9f\xfc?\u06fb\xd2\xe0:\xaa3{\uef7d\xbcE\xfb\xd3\xf2$\u02ca6\x8c\x1d/x\x19\xc6\xc66v\x8c\x1c\x98\x94\xcb\xd4\f\x1e\x02\xe4G25E\xe18\x19\xa8\u0250T`H\x82a\x96\x84Jf\x8a\u0270XP@\xa8\n!\xc9\x04\xc8x\x02\x89\a\x13\x1b\xe3\x15\x19[\xc6c\xcb\xd6bY\x8b%\xdbOz\u04b3\x96\xb7t\xf7\xbd\xf3\xa3\xbb_w?=9T*\x10\x92\xf4\xf7G\xb6\xf4\xd4oQ\xdfs\xbf{\xbe\xf3\x9d\x0f\x86a@OM[G\xe5\x1c\x8b\u05dc\xbc\xd3[\xfa\x83\x8bs\xc7\fj\x06\xee6}\v\xa0DNES\xe4aT\x80Y\\\r?\xc0\x02p\x80\xdb\x04t\x99\xda\xca\x0e\x93;\xd6sN\x10N\x929s\xd7\x103\xb2~GuCs\x00\xde\xfe\xbf\xbd9\xe4\xb6\xf0\xbb\xaf\u0248\xa3\xef'\xd9l\xdetx\xb4\u01aaZ\x80k\xda\xc9\xdat\x89\xbb{\x96{\x8a\xc1b\xc6)\x04\x96~\xdcV\xbc\x10\x97g\x8b\xd3[`\x1e\x9f$E\x85\x12\n \x99\xb8\x82\xc1\xf7\xf6\xa1\xfd\xa7O\xa1\xef\u0777\xf2r\xe2\x84R\xd3\b\x8b1\b\xce\rn\x18,\x12)CCC\x03\xaa\xab\xab/,\\\xb8\xf0\xf5\x96\x96\x96\xc7ZZ6\x9es\xff\xde7\xbf\xf9\x10Y\xb6l\x99\xb8\xed\xb6\xbf\xf6\x17\xaf\x0f\xe6~\xe4\u01b7\xbe\xf5M\xf2\xe8\xa3\xff$\x00\xa0\xad\xed\xf0\x86\x1d;\x9e\xf9\xcf\xfd\xfb\x0f,s/\x01\xaf\u0305\xe4\xe4\xa2\xc45\x9d&\x97\x1b\xcf*'0\xcb88\u0324C\x90\x876\u0235\x17\x80\u02e6\xd56\xf9\xa2\xc4\xecj\x14 \x969\x94p\x81\"q\x15\x05\x85\xd7\u070b\xe4Q\x9c\xe4\xd0\x14\x94\x98\xf2=B\xecY\x1e\xf6\xa7 r\xe4\x92\xe6\xc6B@\xac\xe767\x99,\x03\xef\xca\xfeM\x1bY1\xc3\u01c6\xbbOA\xc8\xd5\xec\v\xab\x17\x80xL\xbe$\xd7H;\xee\xca\u0429e\x8aEe\x19JH\x8561\x81\xe1\xe3\xef\xa0\xe3\xcdW\xd0\xf5\xf6N$\xc7F\xf2\x838\xa1`\x8cZ\x9b\tGEy\x05\xe6\u039d\x8b\x9a\x9a\xe8\xb1\r\x1b6\xec\u07f6\ud2ed\x8a\x12<\xed\xfe\xbd\x05\v\xaeEkk+\u05ad\xfb\x94\xbf`}0\xf7\xe3j\xf1\xe0\x83_'\xdf\xfe\xf6cV3\xa5\xa8\u07fe\xfd\xe1\xc7\xf6\xed\xdb\xf7\u064e\x8e3\x88\xc7\u3982\u015d\xa1Sj6n\x00\xe0Z\x06\xc1\xb2J\xd4\u07f8\tsW\u0742\xaa\xeb\u05a00Z\vC3`his\xaa}\x0e\xaa\x12\xe1:\xda\xc3\xd5\xe5\txG\xb3[w\xa6c\x80\ubc3c\xd9\xd6~kX\xb4\x10\xb3\xdf\xd0\xf9\x9a\x98\xf2\xb5\xc5S7\x9dB\\\xad\xed\"\xbf.\xfb>bg\x8ea\xe4\\\a\x92c1\xa4\xa7&\xc0\r}\xc6\xe7I)\u02f6\u061b_\xad\xb1mB\x18\xe9t\x9a\x97\x95\x95\xc9s\xe6\xd4`\xfe\xfc\xf9\xf1\x95+\xff\xfc\xdf\xee\xbf\xffk\xdf%\x84d\xc7\x02}\xe7;\xffJ\x1ex\xe0\x1f}y\xa1\x0f\xe6~|T\xf1\xea\xab?\xc3\xee\u077b\xc9SO\xed\xc8.\xbcw\xde\u0673\xf1\xe5\x97\u007f\xf2\x8d\xe3\xc7O\xac\xef\xec\xec\xc4\xe8\u8a1d\x9cR\x0f\x8d`\x1d\xbd\x05\u7812\x84py\r\xe6,[\x83\xba\x1bnA\xe5\u0095(\xaem\x02Q$\xe8i\u00f4\b\xe0\x1c\x82\xebV\xd6\xeed\xa6\xe6\x14!W\xcb\xd1U-\x02\xf3\xd3(\xf4K\xd5\x00\x00\v\xecIDAT\"\x1e\x83+K\x8d\xe1\xc9\xfc\x89\xfd\xe2g\aL\x9b\xe20r&M\xb8\x9b\x99f{\x1dW\x1b\xd6\xecH\xfeL\x12;+[\xb4~n\xb8\xb2\xf3|\x1c8r\b!\x02\xaf2\x881\x06EU!)\x12\x88\x00\u04898&c\x171q\xb1\x0f\xa3\xbd\x1d\x88u\x9d\xc4\u04296\\\x19\ua0de\x9a\xc2\f{\a\xf7\xe9\x8b8~\xf2\x0emC@\b\x11\x9a\x96\xe1\xa1P\x98\u035bw\r\xea\xea\xea\x06\x97-[\xba\xf3\xcb_\xfe\u04bfG\"\x95=\xeekuvv`\u07bc\x05\xfe\xe2\xf2\xc1\u070f\xdfG\xb4\xb6>\x8d\xad[\xb7\xb9\x8e\xf9B~\xe9\xa5\x1f\u07bdk\u05ee;\xfb\xfb\a\u059dF\xb2lR.yd\x83e\xd6\xf8\xca*\x80:\x1b\x94p\x9aw(1\x1b\xf8)\x01\xb3(-JMb\x852\n\x89\x02Z:\x83\x89K\x03&h\xf7\x9e\xc1X\xdfY\x8c\xf5wc|\xa0\v\x13\x17\a\xbd\xe3\xe0(3yn\xeb\x14E\x89W\xc6#\xf2\fN\x15B\x80R\x02YV \xcb\x12\x1a\x1b\x1b\xd1\xdc\xdc<\x19\x8dV\xb5\xdeu\u05dd?Y\xb5jM\x9b\xfb\xf1\xdf\xff\xfe\xe3\xb8\uffbf\xf7\x17\x90\x0f\xe6~|\x9c\xe2\x95W\xfe\v[\xb6\u070e#G\x0ea\u03de\xbd\xec\x81\a\x1e\xb4\x95/U/\xbf\xfc\u04a7\xdb\xdbO\xdc\xdd\xd6vt\xfd\xa9S\xa7\x90H$\x90N\xa7=L\xc5L\n\xc603hj\x82<\xa1\x14L\x0e@\t\x17A\n\x85!\a\v\xa0\x84\x8b\xa0\x16\x95!\x14\xa9B\xb8j.\xc2\x15s\x10(.\x85\x1a.B\xb0\xb8\x14\xc1\x92\n\xa8\x85%\x90\x14\x15\xce \x04\x0eC7\xcci\xedB\x98\x13L\x05\xcf\x0e\f\xa6\xd4\xd2e\u00dc\x96\x03 ;\xcb\xd46\xb0\u02b5\x9b\xe5B@\xe3f\xe1\xd5\x00\xcd\u038c\x13v\xeaL\b\xe0\x18E\xb9\xc6\u06f9\xac\xa9,>\u01b1\x036\v\xae\xb6\xbe\x9c\x11\xc7!\xd11,s\rL&f\x87'\x17\x02\f\xe6&\x96\x99\x9e\u0115\xe1~\x8c\xf5w\"~\xfe,F{;\x90\x18\xee\xc3\xc4\xf0\x00&b\x17\xc0u\x87\xf3\xa6L\u029aY\x99\xb2A\xe21\xf52\x9d\x10E\xdeF,\xc30\x04!\x84\x84B!\x14\x15\x15\xa2\xb1\xb1\x11\x8b\x17/>\xdd\xd4\xd4\xf8\x8b\xa5K\x97\xbd|\xd3M-\xed\x00\xb0~\xfd\x8dt\u06f6m\xb8\xf3\xce\xcf\xf9\xea\x14\x1f\xcc\xfd\xf8C\x897\xde\xf8\x05}\xe3\x8d_\xb2'\x9ex\xd2V\xbe\x84\u007f\xf0\x83\x176\x1f=\xfa\u07b7\x8e\x1e=\xba``\xa0\x1f\xb1X\f\x9a\xa6\xe7-\t\xba\xb3C\x13\xe0I6\xd3\x16\x82Cp\xd7\fw\xca \xa9A\u0221\x02H\x81\x10\xa4@\x10J\xa8\x00\x81\xc2R\x84\"QD\x1a\xe6#\u04bc\b\xa5\x9f\xb8\x16\xe1\xb2JH\x8a\nI\x92 I\xd41\xc4\x12\x00\xb8\x01\xce-B\xc5eW\xeb1\x8d\xb2\xa8\ffm2 \x04\x19\x01d,x\xd2\f\xb3\u02d2[\x1bD\x96\n\xe2\xe6\tA\b\x93'2\xbf\xaf\xc3\xd0\xd20\xd2Ip]\x03\xd7M\x1baSJHA\xc0A\xb9n\x82\xb3\xaeA\x18:\fC\x03\x84\x80\x1a.\x82\x1c\f\x9b\x12A-\x8d\xf4D\x02S\xf1\u02d8\x8c\rc\xf2R?\x12\xc3\x03\x98\x8a_F*1\x8aTb\x14\xc9\u0118\xc7\a\x85P\x06\xcaXv\x93\xb3\v\x964\x0f\x80C\x88\x19\x12Ka\x06!\x04(**FYY\x19\xae\xb9\xa6\x19MM\x8d?^\xb0`\xc1\xd3\u06f6}\xb9\x8b\x102l?]k\xeb\xd3l\xeb\xd6m\xba\xbf2|0\xf7\xe3\x0f4\xac\x81\xd1n\xe5\vmm\xdd\xf1\xb9\u00c7\x0f\xdf\u007f\xf2\xe4\xff-\x1d\x19\x19\xc1\xf0\xf002\x99\x8cA\b\x04\xa5L2\v\x9d9\x1c\xac\xc5E\x10\xf7\x84g\xe7\xa2\x10\xdc\u021b5RJ!\a\xc3P\vK\x10,-G\u025cFT^\xb3\b%\xd1Z\x14\x94U \\Z\t\xb5\xa8\x14r(\fI\t\x80I2d\x89\x81P\xe6iN2\v\x8f\xe6f\xc2u\x03\x84\xeb\xa0\xe0\xa000\x9d\xd611\x95\xc4\u0115+\x98\x1a\x1f\xc5\xd4D\x02\xa9\xa9\t\xe8\xa9$2\xa9\x142\x13cHO\x8cCKN\xc2H\xa7`d\xd204\xf3\xab\x9eJ\x82k\xa6m\xb00\f\ap\xadZ\x02\xb1\xc0\x94s\xdd,\x06\x1b\xe6\xfb\xb4\x1b\xb3\f-\x03\xaee\xa0k\x19\xf3\u07fav\xf5\x05\x9d\x95\x8bRPP\xc7\xc7\x1c\x8e\u01ce;\x03'\xc43(\x9b\xeb\xban\b\xc1%UUI$\x12AYY\x19\xae\xbdv~b\xf9\xf2\xa5\xaf/_\xbe\xec_n\xbe\xf93\x1e>\xfc\xb5\xd7^!\xd5\xd5Q\xb1j\xd5\x1a\u007f1\xf8`\xee\xc7\x1fC\xec\xdc\xf9sr\xeb\xad\u007f)r8\u04ed\x1d\x1d\x1d[\xbb\xba\xba\xe7\x0f\r\r\x05c\xb1\x18\xe2\xf11!\x047\b\xa1T\bn+(H.\x1d\xe3\xf6Gw\xeeT\xe2\x92\xf59\xed\xa3B\x18.\x87?\x02I\r\x80\xc92\x98\xacB\t\x86\xa0\x14\x14\xa1\xb8\xbc\x1a\x85\x955\b\x16\x95@\r\x86!)*\x18\xa5Y!$#\x020t\x18\x99\f2\xa9i\xd3\xe27\x93\x82\xd0\u04d8\xba2\x8exl\x04\x93\x93W\x90\x9e\x9e\x86\xaee\xc0\r\xdd\x04^+\x03\xe7\u0724v\x84\xf8\xe8Tw6\x10\x13W\xb3\x8eS\xb4\x9c\xc9w\xbb5\xdd\xc4\xf1+\x067\x83J\x12#\x95\x95\x95(++CAA\xc1x]]]\xfb\xfa\xf5\xeb\xf7\xdes\xcf\u059f\x12B:\xdc\xd7{\xf0\xc1\xaf\x93{\xef\xbdW\xd4\xd4\xd4\xfa7\xbf\x0f\xe6~\xfc\xb1\xc5\xd3O?\x85S\xa7N\x91'\x9ex\u049d\xa9\xb3C\x87\x0e\u073as\xe7\xceM\xdd\xdd=\xab\x93\xc9\xe4\x82X,\x86\x81\x81ALOOA\xd7uLO'!\xc4\a2\xac\xbd\u028dLr\xe7\xd2\xffN\x16E\xde\xd1l\x1f\xe5\x02\xf5H\x02]_\xad\xb6y\u4302\xcb97y\u078d\xfd\x18\xce\x058\xe7\x90$\t\xaa\xaa\xa2\xa8\xa8\b\xd1h\x14\x91H\xd9XII\xc9\u19a6\xa6C\x1b7\xb6\x1c\xfd\u0527n\xdaE\b\xf1\xf0\xdfo\xbe\xf9+|\xfa\xd3\u007f\xe1\xdf\xec>\x98\xfb\xf1\xa7\x10\xb3\xa9\x18\x84\xe0\u05fe\xf8\xe2\x8b\x1b\xdb\xdb\xdb\xe7\uaeb6\xe2\u0295\x89\xf2s\xe7\xceM\x85\xc3\xe1\u56a6\x05{{\xcf#\x91H \x93I\xc308\f\xc3@&\x93\xf9\xe3\\x\xb9Y2!\x1e\xd31\xea\xea\xc1w\x17D\xed,;\xdf\x06f\u007f\x9fR{\xec\x9a\xd5\xf9i\xa9V\x18cP\xd5\x00**\xcaQ[[\v\u01a4\xe9`0\xd0Y]]=\xac\xaa\u02ae\xdbn\xdbrv\u035a\xb5\xbf\xca\u05d5\xb9k\xd7/q\xcb-\x9f\xf1on\x1f\xcc\xfd\xf8S\x8c\x8b\x17\x87\x10\x8d\xd6`p\xb0\x8f\xd4\xd6~B\xe4\x1c\xfb\xab\x00\x94\xec\u077b7\xd9\xdb\xdb3\xaf\xaf\xaf\xaf\xee\u0295\xc9\x06Bp\xfd\xc8H\x8c\xc6b#)JiEQQ\u046a\u02d7/c``\x10\x13\x13\x13\u0434\f4M\x83\xae\x1b0\f\x03\x9a\xa6\x9b<\xb7\xdbf\xe0Cj\x11\xbf\x9a\x89\x96\x99\a\x93\x19\xf3D\xb3\t\xf2l\xb9\xbdG\xcbm6\xfa0f\xd3%\xc4j\xa42m\x87\u0740\x9d}FB!\u02e6R\xc56\xb7b\x8cZ\xe0mf\u07a5\xa5%\xa8\xad\xadE0\x18\ucaac\xac\xec\f\x04\x82GC\xa1`\xe7\xbcy\u05cc\xb6\xb4l8\x1f\x8d\xd6^$\x84$\xec\xabvv\x9e!\xf3\xe6\xcd\x17\x00\xb0c\xc7S\u063cy3\xe6\u0319\xeb\xdf\xd0>\x98\xfb\xf1\xa7\x1c==\x9dhj\x9a\a!\x04v\xee\xfc9\x89\xc5b\xec\xc9'\x9f\x16\u01cf\x1f7\xf2\x03\xa6\xa8\xb0\xeeK\xbd\xa3\xe3T\xb8\xaf\xaf\u007fN[[[@Q\xe4\u0159Lf\xe5\u0673g\xb5\xe9\xe9diII\xf1\xba\x8b\x17/\x97\x0e\f\f`||\x1c\xba\xae!\x93\u0450L\x9a\xfe/6\xd8Sk B~\x80\xcf\xef\xed2\xc3\xfb\u071e=*\x04r\x8b\xb7\xb2,\x83Rj6\xf5\xe4\\U\x96e(\xb2\x9c\x05W\x0f\xc7M\x88w,\x9b\x95=\xeb\xba\x0e\u039d\xe9M\xf6\xefp\xceA)\x81$IP\x14\x15\xb2,\x811\x06J\x19dYBqq\xb1\x88F\xa3\xa4\xa4\xa48\x1d\x8f\xc7\x0f\x8c\x8d\x8d\x9fkhh\b44\u05031\xe98\xe7\xbcm\xf5\xea\x1b\x86W\xaf^;F\b\x19\xcd}\xcf\xf7\xddw\xaf\xb4b\xc5r\xb1l\xd92\xbed\xc9R\xf1\xfa\xeb\xff\x83M\x9b6\xfb7\xb0\x0f\xe6~\xf8q\xb5\fW\xe0\u0529\xf7iOO/y\xfb\xed}(,\f\xd3D\xe2\n}\xfc\xf1\xffH\xff\x86\xdf\v\x02\x10\xa9\u0514|\xe4\xc8\xe1\u04b6\xb6cJEE\xf9\xc6\u04e7;\x16\x8d\x8c\u0116\x8d\x8c\x8c.\x1e\x1a\x1a\n'\x12\xe3\xd40\xcc\x06\x97t:\x8d\xa9\xa9)LM%a\xaa\r\t4M\x87\xa6i\xf9\x93k\x80\u0232\fIbfc\x90p\x18sU\r\xa0\xa8\xa8\x10\x81@\x00\x92$\x81s\x81d2\t\x00P\x14\x05\xc1`\x00\x92$\x9bEXY\x02!$I\b\x9d,..DAA\x01\x14EE \xa0BUU(\x8a\n\xc6X\xf6\x89UU\xa5\xc1`\x80^\xb80\xb4\xef\xfc\xf9\xf3\xa7\xc2\xe10K\xa7\u04d9\xea\xea\xea\xe6`0T\xdc\xdf\xdfwZQ\x14c\xee\u0739\xa4\xbe\xbe\x1e\xc5\xc5E\b\x85B2\x80\xc1c\xc7\xda\xf7LNN&\u05acY%777\x19\r\r\r\xf1H\xa4j\n\xf6\xdc\rB\x92\xb9\xeb~\xfb\xf6\x87\x95T*i\xd4\xd7\u05cbU\xabV\x8a\xa5KW\xf8\xdap\x1f\xcc\xfd\xf0\xe3\u00cb\xae\xae3\u063d\xfb\xd7\u0636\xedK\xbf\xf1\xb1\xd3\xd3\x13U\x87\x0e\x1d^\xb7\u007f\xff\x81\x8at:\xb5H\b\\\xdf\xdd\u074dX,\x16\xe6\\\xd4%\x12\t#\x95JrEQKB\xa1\x90\xb5A8\x14\rc\fB\b$\x12\t=\x9dNO\xaa\xaaJM\xe0UH(\x14\x82,+\xa3\x15\x15\x91X}}=\"\x91\x88$\x84\xb8\xd4\xd9\xd9\xf9v:\x9d\x89777K\xcd\xcdM(..\x86$1Z\\\\\"\x15\x16\x16\xbe;22z|\xf5\xea\x1b\fYV\xd9\aY\x8b\x84\x90\xe9<\x9b\x98G\xfe\xf9\xdb\xc4\x0f\u007f\xf8\"\u05ad[\x87\xba\xba\x06\xff\xa6\xf2\xc1\xdc\x0f?>>\xd1\xde\xfe\x1e\x1e}\xf4\x9f\xf1\uaaef}\x90\x93@\xf9\x89\x13\xc7n>r\xa4-}\xe6\xcc\x19\xbd\xb2\xb2\xe2\x9a\xf2\xf2\xc8\n\xceE\x88s\xce3\x99\x8c\xb0\xb2c\x99\x10\x92\xec\xed=\xff\xf6\x85\v\x17\x06\xeb\xea\xeaX]]\x1d\xa9\xae\x8e\xb2\x86\x86\x06\xb2h\u0452vB\xc8\u064f\xe3\xe71<<\x88\xeaj_&\xe8\x87\x1f~\xfc\x81\xc7\xd0\xd0\xc0\xc7\xf2u\xdd\u007f\xff\xdfbp\xb0\xdf\xff\x03\xf9\xf1\xa1\xc7\xff\x03 \x99\rH\xa6\x0e6\x92\x00\x00\x00\x00IEND\xaeB`\x82")
-
-// dashboardDockerfile is the Dockerfile required to build an dashboard container
-// to aggregate various private network services under one easily accessible page.
-var dashboardDockerfile = `
-FROM mhart/alpine-node:latest
-
-RUN \
- npm install connect serve-static && \
- \
- echo 'var connect = require("connect");' > server.js && \
- echo 'var serveStatic = require("serve-static");' >> server.js && \
- echo 'connect().use(serveStatic("/dashboard")).listen(80, function(){' >> server.js && \
- echo ' console.log("Server running on 80...");' >> server.js && \
- echo '});' >> server.js
-
-ADD {{.Network}}.json /dashboard/{{.Network}}.json
-ADD {{.Network}}-cpp.json /dashboard/{{.Network}}-cpp.json
-ADD {{.Network}}-harmony.json /dashboard/{{.Network}}-harmony.json
-ADD {{.Network}}-parity.json /dashboard/{{.Network}}-parity.json
-ADD {{.Network}}-python.json /dashboard/{{.Network}}-python.json
-ADD index.html /dashboard/index.html
-ADD puppeth.png /dashboard/puppeth.png
-
-EXPOSE 80
-
-CMD ["node", "/server.js"]
-`
-
-// dashboardComposefile is the docker-compose.yml file required to deploy and
-// maintain an service aggregating dashboard.
-var dashboardComposefile = `
-version: '2'
-services:
- dashboard:
- build: .
- image: {{.Network}}/dashboard{{if not .VHost}}
- ports:
- - "{{.Port}}:80"{{end}}
- environment:
- - ETHSTATS_PAGE={{.EthstatsPage}}
- - EXPLORER_PAGE={{.ExplorerPage}}
- - WALLET_PAGE={{.WalletPage}}
- - FAUCET_PAGE={{.FaucetPage}}{{if .VHost}}
- - VIRTUAL_HOST={{.VHost}}{{end}}
- logging:
- driver: "json-file"
- options:
- max-size: "1m"
- max-file: "10"
- restart: always
-`
-
-// deployDashboard deploys a new dashboard container to a remote machine via SSH,
-// docker and docker-compose. If an instance with the specified network name
-// already exists there, it will be overwritten!
-func deployDashboard(client *sshClient, network string, conf *config, config *dashboardInfos, nocache bool) ([]byte, error) {
- // Generate the content to upload to the server
- workdir := fmt.Sprintf("%d", rand.Int63())
- files := make(map[string][]byte)
-
- dockerfile := new(bytes.Buffer)
- template.Must(template.New("").Parse(dashboardDockerfile)).Execute(dockerfile, map[string]interface{}{
- "Network": network,
- })
- files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
-
- composefile := new(bytes.Buffer)
- template.Must(template.New("").Parse(dashboardComposefile)).Execute(composefile, map[string]interface{}{
- "Network": network,
- "Port": config.port,
- "VHost": config.host,
- "EthstatsPage": config.ethstats,
- "ExplorerPage": config.explorer,
- "WalletPage": config.wallet,
- "FaucetPage": config.faucet,
- })
- files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
-
- statsLogin := fmt.Sprintf("yournode:%s", conf.ethstats)
- if !config.trusted {
- statsLogin = ""
- }
- indexfile := new(bytes.Buffer)
- bootCpp := make([]string, len(conf.bootnodes))
- for i, boot := range conf.bootnodes {
- bootCpp[i] = "required:" + strings.TrimPrefix(boot, "enode://")
- }
- bootHarmony := make([]string, len(conf.bootnodes))
- for i, boot := range conf.bootnodes {
- bootHarmony[i] = fmt.Sprintf("-Dpeer.active.%d.url=%s", i, boot)
- }
- bootPython := make([]string, len(conf.bootnodes))
- for i, boot := range conf.bootnodes {
- bootPython[i] = "'" + boot + "'"
- }
- template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{
- "Network": network,
- "NetworkID": conf.Genesis.Config.ChainId,
- "NetworkTitle": strings.Title(network),
- "EthstatsPage": config.ethstats,
- "ExplorerPage": config.explorer,
- "WalletPage": config.wallet,
- "FaucetPage": config.faucet,
- "GethGenesis": network + ".json",
- "Bootnodes": conf.bootnodes,
- "BootnodesFlat": strings.Join(conf.bootnodes, ","),
- "Ethstats": statsLogin,
- "Ethash": conf.Genesis.Config.Ethash != nil,
- "CppGenesis": network + "-cpp.json",
- "CppBootnodes": strings.Join(bootCpp, " "),
- "HarmonyGenesis": network + "-harmony.json",
- "HarmonyBootnodes": strings.Join(bootHarmony, " "),
- "ParityGenesis": network + "-parity.json",
- "PythonGenesis": network + "-python.json",
- "PythonBootnodes": strings.Join(bootPython, ","),
- "Homestead": conf.Genesis.Config.HomesteadBlock,
- "Tangerine": conf.Genesis.Config.EIP150Block,
- "Spurious": conf.Genesis.Config.EIP155Block,
- "Byzantium": conf.Genesis.Config.ByzantiumBlock,
- "Constantinople": conf.Genesis.Config.ConstantinopleBlock,
- })
- files[filepath.Join(workdir, "index.html")] = indexfile.Bytes()
-
- // Marshal the genesis spec files for go-ethereum and all the other clients
- genesis, _ := conf.Genesis.MarshalJSON()
- files[filepath.Join(workdir, network+".json")] = genesis
-
- if conf.Genesis.Config.Ethash != nil {
- cppSpec, err := newCppEthereumGenesisSpec(network, conf.Genesis)
- if err != nil {
- return nil, err
- }
- cppSpecJSON, _ := json.Marshal(cppSpec)
- files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON
-
- harmonySpecJSON, _ := conf.Genesis.MarshalJSON()
- files[filepath.Join(workdir, network+"-harmony.json")] = harmonySpecJSON
-
- paritySpec, err := newParityChainSpec(network, conf.Genesis, conf.bootnodes)
- if err != nil {
- return nil, err
- }
- paritySpecJSON, _ := json.Marshal(paritySpec)
- files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON
-
- pyethSpec, err := newPyEthereumGenesisSpec(network, conf.Genesis)
- if err != nil {
- return nil, err
- }
- pyethSpecJSON, _ := json.Marshal(pyethSpec)
- files[filepath.Join(workdir, network+"-python.json")] = pyethSpecJSON
- } else {
- for _, client := range []string{"cpp", "harmony", "parity", "python"} {
- files[filepath.Join(workdir, network+"-"+client+".json")] = []byte{}
- }
- }
- files[filepath.Join(workdir, "puppeth.png")] = dashboardMascot
-
- // Upload the deployment files to the remote server (and clean up afterwards)
- if out, err := client.Upload(files); err != nil {
- return out, err
- }
- defer client.Run("rm -rf " + workdir)
-
- // Build and deploy the dashboard service
- if nocache {
- return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate", workdir, network, network))
- }
- return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate", workdir, network))
-}
-
-// dashboardInfos is returned from an dashboard status check to allow reporting
-// various configuration parameters.
-type dashboardInfos struct {
- host string
- port int
- trusted bool
-
- ethstats string
- explorer string
- wallet string
- faucet string
-}
-
-// Report converts the typed struct into a plain string->string map, containing
-// most - but not all - fields for reporting to the user.
-func (info *dashboardInfos) Report() map[string]string {
- return map[string]string{
- "Website address": info.host,
- "Website listener port": strconv.Itoa(info.port),
- "Ethstats service": info.ethstats,
- "Explorer service": info.explorer,
- "Wallet service": info.wallet,
- "Faucet service": info.faucet,
- }
-}
-
-// checkDashboard does a health-check against a dashboard container to verify if
-// it's running, and if yes, gathering a collection of useful infos about it.
-func checkDashboard(client *sshClient, network string) (*dashboardInfos, error) {
- // Inspect a possible ethstats container on the host
- infos, err := inspectContainer(client, fmt.Sprintf("%s_dashboard_1", network))
- if err != nil {
- return nil, err
- }
- if !infos.running {
- return nil, ErrServiceOffline
- }
- // Resolve the port from the host, or the reverse proxy
- port := infos.portmap["80/tcp"]
- if port == 0 {
- if proxy, _ := checkNginx(client, network); proxy != nil {
- port = proxy.port
- }
- }
- if port == 0 {
- return nil, ErrNotExposed
- }
- // Resolve the host from the reverse-proxy and configure the connection string
- host := infos.envvars["VIRTUAL_HOST"]
- if host == "" {
- host = client.server
- }
- // Run a sanity check to see if the port is reachable
- if err = checkPort(host, port); err != nil {
- log.Warn("Dashboard service seems unreachable", "server", host, "port", port, "err", err)
- }
- // Container available, assemble and return the useful infos
- return &dashboardInfos{
- host: host,
- port: port,
- ethstats: infos.envvars["ETHSTATS_PAGE"],
- explorer: infos.envvars["EXPLORER_PAGE"],
- wallet: infos.envvars["WALLET_PAGE"],
- faucet: infos.envvars["FAUCET_PAGE"],
- }, nil
-}
diff --git a/cmd/puppeth/module_ethstats.go b/cmd/puppeth/module_ethstats.go
index 20b7afe236..cca7fe1650 100644
--- a/cmd/puppeth/module_ethstats.go
+++ b/cmd/puppeth/module_ethstats.go
@@ -25,7 +25,7 @@ import (
"strings"
"text/template"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// ethstatsDockerfile is the Dockerfile required to build an ethstats backend
diff --git a/cmd/puppeth/module_explorer.go b/cmd/puppeth/module_explorer.go
index 427134153b..c6ff5c7767 100644
--- a/cmd/puppeth/module_explorer.go
+++ b/cmd/puppeth/module_explorer.go
@@ -25,7 +25,7 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// explorerDockerfile is the Dockerfile required to run a block explorer.
diff --git a/cmd/puppeth/module_faucet.go b/cmd/puppeth/module_faucet.go
index 976bf04d00..528c2023b5 100644
--- a/cmd/puppeth/module_faucet.go
+++ b/cmd/puppeth/module_faucet.go
@@ -26,8 +26,8 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// faucetDockerfile is the Dockerfile required to build an faucet container to
diff --git a/cmd/puppeth/module_nginx.go b/cmd/puppeth/module_nginx.go
index 35c0efc8ad..69cc7fcd48 100644
--- a/cmd/puppeth/module_nginx.go
+++ b/cmd/puppeth/module_nginx.go
@@ -24,7 +24,7 @@ import (
"path/filepath"
"strconv"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// nginxDockerfile is theis the Dockerfile required to build an nginx reverse-
diff --git a/cmd/puppeth/module_node.go b/cmd/puppeth/module_node.go
index 54e7e7a43d..a52a959ced 100644
--- a/cmd/puppeth/module_node.go
+++ b/cmd/puppeth/module_node.go
@@ -26,8 +26,8 @@ import (
"strings"
"text/template"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// nodeDockerfile is the Dockerfile required to run an Ethereum node.
diff --git a/cmd/puppeth/module_wallet.go b/cmd/puppeth/module_wallet.go
index 4bbcac2277..25c630e245 100644
--- a/cmd/puppeth/module_wallet.go
+++ b/cmd/puppeth/module_wallet.go
@@ -25,7 +25,7 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// walletDockerfile is the Dockerfile required to run a web wallet.
diff --git a/cmd/puppeth/puppeth.go b/cmd/puppeth/puppeth.go
index f9b8fe4811..5fa0addb21 100644
--- a/cmd/puppeth/puppeth.go
+++ b/cmd/puppeth/puppeth.go
@@ -23,7 +23,7 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/puppeth/ssh.go b/cmd/puppeth/ssh.go
index 158261ce05..72aedd4a6f 100644
--- a/cmd/puppeth/ssh.go
+++ b/cmd/puppeth/ssh.go
@@ -28,7 +28,7 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
)
diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go
index 14d619716d..c4ac5d9094 100644
--- a/cmd/puppeth/wizard.go
+++ b/cmd/puppeth/wizard.go
@@ -30,9 +30,9 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/log"
"golang.org/x/crypto/ssh/terminal"
)
diff --git a/cmd/puppeth/wizard_dashboard.go b/cmd/puppeth/wizard_dashboard.go
deleted file mode 100644
index 5f781c4152..0000000000
--- a/cmd/puppeth/wizard_dashboard.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-package main
-
-import (
- "fmt"
-
- "github.com/ethereum/go-ethereum/log"
-)
-
-// deployDashboard queries the user for various input on deploying a web-service
-// dashboard, after which is pushes the container.
-func (w *wizard) deployDashboard() {
- // Select the server to interact with
- server := w.selectServer()
- if server == "" {
- return
- }
- client := w.servers[server]
-
- // Retrieve any active dashboard configurations from the server
- infos, err := checkDashboard(client, w.network)
- if err != nil {
- infos = &dashboardInfos{
- port: 80,
- host: client.server,
- }
- }
- existed := err == nil
-
- // Figure out which port to listen on
- fmt.Println()
- fmt.Printf("Which port should the dashboard listen on? (default = %d)\n", infos.port)
- infos.port = w.readDefaultInt(infos.port)
-
- // Figure which virtual-host to deploy the dashboard on
- infos.host, err = w.ensureVirtualHost(client, infos.port, infos.host)
- if err != nil {
- log.Error("Failed to decide on dashboard host", "err", err)
- return
- }
- // Port and proxy settings retrieved, figure out which services are available
- available := make(map[string][]string)
- for server, services := range w.services {
- for _, service := range services {
- available[service] = append(available[service], server)
- }
- }
- for _, service := range []string{"ethstats", "explorer", "wallet", "faucet"} {
- // Gather all the locally hosted pages of this type
- var pages []string
- for _, server := range available[service] {
- client := w.servers[server]
- if client == nil {
- continue
- }
- // If there's a service running on the machine, retrieve it's port number
- var port int
- switch service {
- case "ethstats":
- if infos, err := checkEthstats(client, w.network); err == nil {
- port = infos.port
- }
- case "explorer":
- if infos, err := checkExplorer(client, w.network); err == nil {
- port = infos.webPort
- }
- case "wallet":
- if infos, err := checkWallet(client, w.network); err == nil {
- port = infos.webPort
- }
- case "faucet":
- if infos, err := checkFaucet(client, w.network); err == nil {
- port = infos.port
- }
- }
- if page, err := resolve(client, w.network, service, port); err == nil && page != "" {
- pages = append(pages, page)
- }
- }
- // Promt the user to chose one, enter manually or simply not list this service
- defLabel, defChoice := "don't list", len(pages)+2
- if len(pages) > 0 {
- defLabel, defChoice = pages[0], 1
- }
- fmt.Println()
- fmt.Printf("Which %s service to list? (default = %s)\n", service, defLabel)
- for i, page := range pages {
- fmt.Printf(" %d. %s\n", i+1, page)
- }
- fmt.Printf(" %d. List external %s service\n", len(pages)+1, service)
- fmt.Printf(" %d. Don't list any %s service\n", len(pages)+2, service)
-
- choice := w.readDefaultInt(defChoice)
- if choice < 0 || choice > len(pages)+2 {
- log.Error("Invalid listing choice, aborting")
- return
- }
- var page string
- switch {
- case choice <= len(pages):
- page = pages[choice-1]
- case choice == len(pages)+1:
- fmt.Println()
- fmt.Printf("Which address is the external %s service at?\n", service)
- page = w.readString()
- default:
- // No service hosting for this
- }
- // Save the users choice
- switch service {
- case "ethstats":
- infos.ethstats = page
- case "explorer":
- infos.explorer = page
- case "wallet":
- infos.wallet = page
- case "faucet":
- infos.faucet = page
- }
- }
- // If we have ethstats running, ask whether to make the secret public or not
- if w.conf.ethstats != "" {
- fmt.Println()
- fmt.Println("Include ethstats secret on dashboard (y/n)? (default = yes)")
- infos.trusted = w.readDefaultString("y") == "y"
- }
- // Try to deploy the dashboard container on the host
- nocache := false
- if existed {
- fmt.Println()
- fmt.Printf("Should the dashboard be built from scratch (y/n)? (default = no)\n")
- nocache = w.readDefaultString("n") != "n"
- }
- if out, err := deployDashboard(client, w.network, &w.conf, infos, nocache); err != nil {
- log.Error("Failed to deploy dashboard container", "err", err)
- if len(out) > 0 {
- fmt.Printf("%s\n", out)
- }
- return
- }
- // All ok, run a network scan to pick any changes up
- w.networkStats()
-}
diff --git a/cmd/puppeth/wizard_ethstats.go b/cmd/puppeth/wizard_ethstats.go
index fb2529c267..21b923dacd 100644
--- a/cmd/puppeth/wizard_ethstats.go
+++ b/cmd/puppeth/wizard_ethstats.go
@@ -20,7 +20,7 @@ import (
"fmt"
"sort"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// deployEthstats queries the user for various input on deploying an ethstats
diff --git a/cmd/puppeth/wizard_explorer.go b/cmd/puppeth/wizard_explorer.go
index 413511c1c3..5723174c65 100644
--- a/cmd/puppeth/wizard_explorer.go
+++ b/cmd/puppeth/wizard_explorer.go
@@ -21,7 +21,7 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// deployExplorer creates a new block explorer based on some user input.
diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go
index 9a429bc96d..5c145d5447 100644
--- a/cmd/puppeth/wizard_faucet.go
+++ b/cmd/puppeth/wizard_faucet.go
@@ -20,8 +20,8 @@ import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// deployFaucet queries the user for various input on deploying a faucet, after
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 713dd7a03d..9c036c9873 100644
--- a/cmd/puppeth/wizard_genesis.go
+++ b/cmd/puppeth/wizard_genesis.go
@@ -24,22 +24,22 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
"context"
"math/big"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- blockSignerContract "github.com/ethereum/go-ethereum/contracts/blocksigner"
- multiSignWalletContract "github.com/ethereum/go-ethereum/contracts/multisigwallet"
- randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize"
- validatorContract "github.com/ethereum/go-ethereum/contracts/validator"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ blockSignerContract "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner"
+ multiSignWalletContract "github.com/XinFinOrg/XDPoSChain/contracts/multisigwallet"
+ randomizeContract "github.com/XinFinOrg/XDPoSChain/contracts/randomize"
+ validatorContract "github.com/XinFinOrg/XDPoSChain/contracts/validator"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
// makeGenesis creates a new genesis struct based on some user input.
@@ -122,8 +122,8 @@ func (w *wizard) makeGenesis() {
genesis.Config.XDPoS.Period = uint64(w.readDefaultInt(2))
fmt.Println()
- fmt.Println("How many XDC should be rewarded to masternode? (default = 5000)")
- genesis.Config.XDPoS.Reward = uint64(w.readDefaultInt(5000))
+ fmt.Println("How many Ethers should be rewarded to masternode? (default = 10)")
+ genesis.Config.XDPoS.Reward = uint64(w.readDefaultInt(10))
fmt.Println()
fmt.Println("Who own the first masternodes? (mandatory)")
@@ -152,7 +152,7 @@ func (w *wizard) makeGenesis() {
}
}
validatorCap := new(big.Int)
- validatorCap.SetString("10000000000000000000000000", 10)
+ validatorCap.SetString("50000000000000000000000", 10)
var validatorCaps []*big.Int
genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65)
for i, signer := range signers {
@@ -171,7 +171,7 @@ func (w *wizard) makeGenesis() {
genesis.Config.XDPoS.Gap = uint64(w.readDefaultInt(450))
fmt.Println()
- fmt.Println("What is foundation wallet address? (default = xdc746249C61f5832C5eEd53172776b460491bDcd5C)")
+ fmt.Println("What is foundation wallet address? (default = xdc0000000000000000000000000000000000000068)")
genesis.Config.XDPoS.FoudationWalletAddr = w.readDefaultAddress(common.HexToAddress(common.FoudationAddr))
// Validator Smart Contract Code
@@ -231,8 +231,8 @@ func (w *wizard) makeGenesis() {
code, _ = contractBackend.CodeAt(ctx, multiSignWalletAddr, nil)
storage = make(map[common.Hash]common.Hash)
contractBackend.ForEachStorageAt(ctx, multiSignWalletAddr, nil, f)
- fBalance := big.NewInt(0) // 3 billion
- fBalance.Add(fBalance, big.NewInt(0*1000*1000*1000))
+ fBalance := big.NewInt(0) // 16m
+ fBalance.Add(fBalance, big.NewInt(16*1000*1000))
fBalance.Mul(fBalance, big.NewInt(1000000000000000000))
genesis.Alloc[common.HexToAddress(common.FoudationAddr)] = core.GenesisAccount{
Balance: fBalance,
@@ -298,24 +298,24 @@ func (w *wizard) makeGenesis() {
storage = make(map[common.Hash]common.Hash)
contractBackend.ForEachStorageAt(ctx, multiSignWalletTeamAddr, nil, f)
// Team balance.
- balance := big.NewInt(0) // 20 billion
- balance.Add(balance, big.NewInt(30*1000*1000))
- balance.Mul(balance, big.NewInt(1000000000000000000))
- subBalance := big.NewInt(0) // i * 50k
- subBalance.Add(subBalance, big.NewInt(int64(len(signers))*10*1000*1000))
- subBalance.Mul(subBalance, big.NewInt(1000000000000000000))
- balance.Sub(balance, subBalance) // 12m - i * 50k
- genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{
+ balance := big.NewInt(0) // 12m
+ balance.Add(balance, big.NewInt(12*1000*1000))
+ balance.Mul(balance, big.NewInt(1000000000000000000))
+ subBalance := big.NewInt(0) // i * 50k
+ subBalance.Add(subBalance, big.NewInt(int64(len(signers))*50*1000))
+ subBalance.Mul(subBalance, big.NewInt(1000000000000000000))
+ balance.Sub(balance, subBalance) // 12m - i * 50k
+ genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{
Balance: balance,
Code: code,
Storage: storage,
}
fmt.Println()
- fmt.Println("What is swap wallet address for fund 37.47Billion XDC?")
+ fmt.Println("What is swap wallet address for fund 55m XDC?")
swapAddr := *w.readAddress()
- baseBalance := big.NewInt(0) // 14.5Billion
- baseBalance.Add(baseBalance, big.NewInt(3747*1000*1000*10))
+ baseBalance := big.NewInt(0) // 55m
+ baseBalance.Add(baseBalance, big.NewInt(55*1000*1000))
baseBalance.Mul(baseBalance, big.NewInt(1000000000000000000))
genesis.Alloc[swapAddr] = core.GenesisAccount{
Balance: baseBalance,
diff --git a/cmd/puppeth/wizard_intro.go b/cmd/puppeth/wizard_intro.go
index 60aa0f7ffb..9a8d345f35 100644
--- a/cmd/puppeth/wizard_intro.go
+++ b/cmd/puppeth/wizard_intro.go
@@ -26,7 +26,7 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// makeWizard creates and returns a new puppeth wizard.
diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go
index 90bf7ae3c8..b8bdd19fb0 100644
--- a/cmd/puppeth/wizard_netstats.go
+++ b/cmd/puppeth/wizard_netstats.go
@@ -23,8 +23,8 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/log"
"github.com/olekukonko/tablewriter"
)
@@ -156,14 +156,6 @@ func (w *wizard) gatherStats(server string, pubkey []byte, client *sshClient) *s
} else {
stat.services["faucet"] = infos.Report()
}
- logger.Debug("Checking for dashboard availability")
- if infos, err := checkDashboard(client, w.network); err != nil {
- if err != ErrServiceUnknown {
- stat.services["dashboard"] = map[string]string{"offline": err.Error()}
- }
- } else {
- stat.services["dashboard"] = infos.Report()
- }
// Feed and newly discovered information into the wizard
w.lock.Lock()
defer w.lock.Unlock()
diff --git a/cmd/puppeth/wizard_network.go b/cmd/puppeth/wizard_network.go
index d780c550b1..ab24768f2c 100644
--- a/cmd/puppeth/wizard_network.go
+++ b/cmd/puppeth/wizard_network.go
@@ -20,7 +20,7 @@ import (
"fmt"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// manageServers displays a list of servers the user can disconnect from, and an
@@ -177,7 +177,6 @@ func (w *wizard) deployComponent() {
fmt.Println(" 4. Explorer - Chain analysis webservice (ethash only)")
fmt.Println(" 5. Wallet - Browser wallet for quick sends")
fmt.Println(" 6. Faucet - Crypto faucet to give away funds")
- fmt.Println(" 7. Dashboard - Website listing above web-services")
switch w.read() {
case "1":
@@ -192,8 +191,6 @@ func (w *wizard) deployComponent() {
w.deployWallet()
case "6":
w.deployFaucet()
- case "7":
- w.deployDashboard()
default:
log.Error("That's not something I can do")
}
diff --git a/cmd/puppeth/wizard_nginx.go b/cmd/puppeth/wizard_nginx.go
index 4eeae93a0b..280be8bba8 100644
--- a/cmd/puppeth/wizard_nginx.go
+++ b/cmd/puppeth/wizard_nginx.go
@@ -19,7 +19,7 @@ package main
import (
"fmt"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// ensureVirtualHost checks whether a reverse-proxy is running on the specified
diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go
index d766ab2cf3..13c9efb9f6 100644
--- a/cmd/puppeth/wizard_node.go
+++ b/cmd/puppeth/wizard_node.go
@@ -21,9 +21,9 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// deployNode creates a new node configuration based on some user input.
diff --git a/cmd/puppeth/wizard_wallet.go b/cmd/puppeth/wizard_wallet.go
index 933cd9ae59..fa634945a0 100644
--- a/cmd/puppeth/wizard_wallet.go
+++ b/cmd/puppeth/wizard_wallet.go
@@ -21,7 +21,7 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// deployWallet creates a new web wallet based on some user input.
diff --git a/cmd/rlpdump/main.go b/cmd/rlpdump/main.go
index d0f993c5b8..fcd900e52b 100644
--- a/cmd/rlpdump/main.go
+++ b/cmd/rlpdump/main.go
@@ -26,7 +26,7 @@ import (
"os"
"strings"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
var (
diff --git a/cmd/swarm/config.go b/cmd/swarm/config.go
index c6929ae591..598985347e 100644
--- a/cmd/swarm/config.go
+++ b/cmd/swarm/config.go
@@ -28,13 +28,13 @@ import (
cli "gopkg.in/urfave/cli.v1"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/node"
"github.com/naoina/toml"
- bzzapi "github.com/ethereum/go-ethereum/swarm/api"
+ bzzapi "github.com/XinFinOrg/XDPoSChain/swarm/api"
)
var (
@@ -84,7 +84,7 @@ var tomlSettings = toml.Config{
MissingField: func(rt reflect.Type, field string) error {
link := ""
if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
- link = fmt.Sprintf(", check github.com/ethereum/go-ethereum/swarm/api/config.go for available fields")
+ link = fmt.Sprintf(", check github.com/XinFinOrg/XDPoSChain/swarm/api/config.go for available fields")
}
return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link)
},
diff --git a/cmd/swarm/config_test.go b/cmd/swarm/config_test.go
index 9bf584f50c..a0ff94e916 100644
--- a/cmd/swarm/config_test.go
+++ b/cmd/swarm/config_test.go
@@ -25,9 +25,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/swarm"
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
+ "github.com/XinFinOrg/XDPoSChain/swarm"
+ "github.com/XinFinOrg/XDPoSChain/swarm/api"
"github.com/docker/docker/pkg/reexec"
)
diff --git a/cmd/swarm/db.go b/cmd/swarm/db.go
index dfd2d069b9..6435db2f07 100644
--- a/cmd/swarm/db.go
+++ b/cmd/swarm/db.go
@@ -22,9 +22,9 @@ import (
"os"
"path/filepath"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/swarm/storage"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/hash.go b/cmd/swarm/hash.go
index 792e8d0d7a..fca405ea26 100644
--- a/cmd/swarm/hash.go
+++ b/cmd/swarm/hash.go
@@ -21,8 +21,8 @@ import (
"fmt"
"os"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/swarm/storage"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/list.go b/cmd/swarm/list.go
index 57b5517c6e..e8772562c4 100644
--- a/cmd/swarm/list.go
+++ b/cmd/swarm/list.go
@@ -22,8 +22,8 @@ import (
"strings"
"text/tabwriter"
- "github.com/ethereum/go-ethereum/cmd/utils"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ swarm "github.com/XinFinOrg/XDPoSChain/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go
index a136885012..3f8a495771 100644
--- a/cmd/swarm/main.go
+++ b/cmd/swarm/main.go
@@ -28,22 +28,22 @@ import (
"strings"
"syscall"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/swarm"
- bzzapi "github.com/ethereum/go-ethereum/swarm/api"
- swarmmetrics "github.com/ethereum/go-ethereum/swarm/metrics"
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/console"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+ "github.com/XinFinOrg/XDPoSChain/internal/debug"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/node"
+ "github.com/XinFinOrg/XDPoSChain/p2p"
+ "github.com/XinFinOrg/XDPoSChain/p2p/discover"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/swarm"
+ bzzapi "github.com/XinFinOrg/XDPoSChain/swarm/api"
+ swarmmetrics "github.com/XinFinOrg/XDPoSChain/swarm/metrics"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/manifest.go b/cmd/swarm/manifest.go
index 41a69a5d05..8be0a08644 100644
--- a/cmd/swarm/manifest.go
+++ b/cmd/swarm/manifest.go
@@ -24,9 +24,9 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/swarm/api"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/swarm/api"
+ swarm "github.com/XinFinOrg/XDPoSChain/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/run_test.go b/cmd/swarm/run_test.go
index 594cfa55cb..6eb5addf68 100644
--- a/cmd/swarm/run_test.go
+++ b/cmd/swarm/run_test.go
@@ -26,14 +26,14 @@ import (
"testing"
"time"
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
+ "github.com/XinFinOrg/XDPoSChain/internal/cmdtest"
+ "github.com/XinFinOrg/XDPoSChain/node"
+ "github.com/XinFinOrg/XDPoSChain/p2p"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
+ "github.com/XinFinOrg/XDPoSChain/swarm"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/internal/cmdtest"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/swarm"
)
func init() {
diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go
index 9f4c525bb9..ea16fcfa90 100644
--- a/cmd/swarm/upload.go
+++ b/cmd/swarm/upload.go
@@ -30,8 +30,8 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ swarm "github.com/XinFinOrg/XDPoSChain/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index c0af4c13e7..161a65a417 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -27,15 +27,15 @@ import (
"strings"
"syscall"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/internal/debug"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/node"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
const (
@@ -178,7 +178,7 @@ func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block
continue
}
// If we're above the chain head, state availability is a must
- if !chain.HasBlockAndState(block.Hash(), block.NumberU64()) {
+ if !chain.HasBlockAndFullState(block.Hash(), block.NumberU64()) {
return blocks[i:]
}
}
@@ -237,7 +237,7 @@ func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, las
}
// ImportPreimages imports a batch of exported hash preimages into the database.
-func ImportPreimages(db *ethdb.LDBDatabase, fn string) error {
+func ImportPreimages(db ethdb.Database, fn string) error {
log.Info("Importing preimages", "file", fn)
// Open the file handle and potentially unwrap the gzip stream
@@ -286,7 +286,7 @@ func ImportPreimages(db *ethdb.LDBDatabase, fn string) error {
// ExportPreimages exports all known hash preimages into the specified file,
// truncating any data already present in the file.
-func ExportPreimages(db *ethdb.LDBDatabase, fn string) error {
+func ExportPreimages(db ethdb.Database, fn string) error {
log.Info("Exporting preimages", "file", fn)
// Open the file handle and potentially wrap with a gzip stream
@@ -302,7 +302,7 @@ func ExportPreimages(db *ethdb.LDBDatabase, fn string) error {
defer writer.(*gzip.Writer).Close()
}
// Iterate over the preimages and export them
- it := db.NewIteratorWithPrefix([]byte("secure-key-"))
+ it := db.NewIterator([]byte("secure-key-"), nil)
for it.Next() {
if err := rlp.Encode(writer, it.Value()); err != nil {
return err
diff --git a/cmd/utils/customflags.go b/cmd/utils/customflags.go
index e5bf8724c1..5f7833daf9 100644
--- a/cmd/utils/customflags.go
+++ b/cmd/utils/customflags.go
@@ -27,7 +27,7 @@ import (
"path"
"strings"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 6665fed0ac..e1a49d48e2 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -28,34 +28,31 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/fdlimit"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/XDPoS"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/dashboard"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/ethstats"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/params"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
+ "github.com/XinFinOrg/XDPoSChain/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/accounts/keystore"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/fdlimit"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/eth"
+ "github.com/XinFinOrg/XDPoSChain/eth/downloader"
+ "github.com/XinFinOrg/XDPoSChain/eth/gasprice"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/metrics"
+ "github.com/XinFinOrg/XDPoSChain/node"
+ "github.com/XinFinOrg/XDPoSChain/p2p"
+ "github.com/XinFinOrg/XDPoSChain/p2p/discover"
+ "github.com/XinFinOrg/XDPoSChain/p2p/discv5"
+ "github.com/XinFinOrg/XDPoSChain/p2p/nat"
+ "github.com/XinFinOrg/XDPoSChain/p2p/netutil"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6"
"gopkg.in/urfave/cli.v1"
)
@@ -142,7 +139,7 @@ var (
}
NetworkIdFlag = cli.Uint64Flag{
Name: "networkid",
- Usage: "Network identifier (integer, 89=XDCchain)",
+ Usage: "Network identifier (integer, 89=XDPoSChain)",
Value: eth.DefaultConfig.NetworkId,
}
TestnetFlag = cli.BoolFlag{
@@ -150,8 +147,8 @@ var (
Usage: "Ropsten network: pre-configured proof-of-work test network",
}
XDCTestnetFlag = cli.BoolFlag{
- Name: "XDC-testnet",
- Usage: "XDC test network",
+ Name: "apothem",
+ Usage: "XDC Apothem Network",
}
RinkebyFlag = cli.BoolFlag{
Name: "rinkeby",
@@ -207,25 +204,10 @@ var (
Name: "lightkdf",
Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength",
}
- // Dashboard settings
- DashboardEnabledFlag = cli.BoolFlag{
- Name: "dashboard",
- Usage: "Enable the dashboard",
- }
- DashboardAddrFlag = cli.StringFlag{
- Name: "dashboard.addr",
- Usage: "Dashboard listening interface",
- Value: dashboard.DefaultConfig.Host,
- }
- DashboardPortFlag = cli.IntFlag{
- Name: "dashboard.host",
- Usage: "Dashboard listening port",
- Value: dashboard.DefaultConfig.Port,
- }
- DashboardRefreshFlag = cli.DurationFlag{
- Name: "dashboard.refresh",
- Usage: "Dashboard metrics collection refresh rate",
- Value: dashboard.DefaultConfig.Refresh,
+ // XDCX settings
+ XDCXEnabledFlag = cli.BoolFlag{
+ Name: "XDCx",
+ Usage: "Enable the XDCX protocol",
}
// Ethash settings
EthashCacheDirFlag = DirectoryFlag{
@@ -323,11 +305,6 @@ var (
Usage: "Percentage of cache memory allowance to use for trie pruning",
Value: 25,
}
- TrieCacheGenFlag = cli.IntFlag{
- Name: "trie-cache-gens",
- Usage: "Number of trie node generations to keep in memory",
- Value: int(state.MaxTrieCacheGen),
- }
// Miner settings
StakingEnabledFlag = cli.BoolFlag{
Name: "mine",
@@ -400,6 +377,11 @@ var (
Usage: "HTTP-RPC server listening interface",
Value: node.DefaultHTTPHost,
}
+ RewoundFlag = cli.IntFlag{
+ Name: "rewound",
+ Usage: "Rewound blocks",
+ Value: 0,
+ }
RPCPortFlag = cli.IntFlag{
Name: "rpcport",
Usage: "HTTP-RPC server listening port",
@@ -550,6 +532,34 @@ var (
Usage: "Minimum POW accepted",
Value: whisper.DefaultMinimumPoW,
}
+ XDCXDataDirFlag = DirectoryFlag{
+ Name: "XDCx.datadir",
+ Usage: "Data directory for the XDCX databases",
+ Value: DirectoryString{filepath.Join(DataDirFlag.Value.String(), "XDCx")},
+ }
+ XDCXDBEngineFlag = cli.StringFlag{
+ Name: "XDCx.dbengine",
+ Usage: "Database engine for XDCX (leveldb, mongodb)",
+ Value: "leveldb",
+ }
+ XDCXDBNameFlag = cli.StringFlag{
+ Name: "XDCx.dbName",
+ Usage: "Database name for XDCX",
+ Value: "XDCdex",
+ }
+ XDCXDBConnectionUrlFlag = cli.StringFlag{
+ Name: "XDCx.dbConnectionUrl",
+ Usage: "ConnectionUrl to database if dbEngine is mongodb. Host:port. If there are multiple instances, separated by comma. Eg: localhost:27017,localhost:27018",
+ Value: "localhost:27017",
+ }
+ XDCXDBReplicaSetNameFlag = cli.StringFlag{
+ Name: "XDCx.dbReplicaSetName",
+ Usage: "ReplicaSetName if Master-Slave is setup",
+ }
+ XDCSlaveModeFlag = cli.BoolFlag{
+ Name: "slave",
+ Usage: "Enable slave mode",
+ }
)
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -1034,6 +1044,42 @@ func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
}
}
+func SetXDCXConfig(ctx *cli.Context, cfg *XDCx.Config, XDCDataDir string) {
+ if ctx.GlobalIsSet(XDCXDataDirFlag.Name) {
+ cfg.DataDir = ctx.GlobalString(XDCXDataDirFlag.Name)
+ } else {
+ // default XDCx datadir: DATADIR/XDCx
+ defaultXDCXDataDir := filepath.Join(XDCDataDir, "XDCx")
+
+ filesInXDCXDefaultDir, _ := WalkMatch(defaultXDCXDataDir, "*.ldb")
+ filesInNodeDefaultDir, _ := WalkMatch(node.DefaultDataDir(), "*.ldb")
+ if len(filesInXDCXDefaultDir) == 0 && len(filesInNodeDefaultDir) > 0 {
+ cfg.DataDir = node.DefaultDataDir()
+ } else {
+ cfg.DataDir = defaultXDCXDataDir
+ }
+ }
+ log.Info("XDCX datadir", "path", cfg.DataDir)
+ if ctx.GlobalIsSet(XDCXDBEngineFlag.Name) {
+ cfg.DBEngine = ctx.GlobalString(XDCXDBEngineFlag.Name)
+ } else {
+ cfg.DBEngine = XDCXDBEngineFlag.Value
+ }
+ if ctx.GlobalIsSet(XDCXDBNameFlag.Name) {
+ cfg.DBName = ctx.GlobalString(XDCXDBNameFlag.Name)
+ } else {
+ cfg.DBName = XDCXDBNameFlag.Value
+ }
+ if ctx.GlobalIsSet(XDCXDBConnectionUrlFlag.Name) {
+ cfg.ConnectionUrl = ctx.GlobalString(XDCXDBConnectionUrlFlag.Name)
+ } else {
+ cfg.ConnectionUrl = XDCXDBConnectionUrlFlag.Value
+ }
+ if ctx.GlobalIsSet(XDCXDBReplicaSetNameFlag.Name) {
+ cfg.ReplicaSetName = ctx.GlobalString(XDCXDBReplicaSetNameFlag.Name)
+ }
+}
+
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// Avoid conflicting network flags
@@ -1138,71 +1184,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
}
}
// TODO(fjl): move trie cache generations into config
- if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
- state.MaxTrieCacheGen = uint16(gen)
- }
-}
-
-// SetDashboardConfig applies dashboard related command line flags to the config.
-func SetDashboardConfig(ctx *cli.Context, cfg *dashboard.Config) {
- cfg.Host = ctx.GlobalString(DashboardAddrFlag.Name)
- cfg.Port = ctx.GlobalInt(DashboardPortFlag.Name)
- cfg.Refresh = ctx.GlobalDuration(DashboardRefreshFlag.Name)
-}
-
-// RegisterEthService adds an Ethereum client to the stack.
-func RegisterEthService(stack *node.Node, cfg *eth.Config) {
- var err error
- if cfg.SyncMode == downloader.LightSync {
- err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- return les.New(ctx, cfg)
- })
- } else {
- err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- fullNode, err := eth.New(ctx, cfg)
- if fullNode != nil && cfg.LightServ > 0 {
- ls, _ := les.NewLesServer(fullNode, cfg)
- fullNode.AddLesServer(ls)
- }
- return fullNode, err
- })
- }
- if err != nil {
- Fatalf("Failed to register the Ethereum service: %v", err)
- }
-}
-
-// RegisterDashboardService adds a dashboard to the stack.
-func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
- stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- return dashboard.New(cfg, commit)
- })
-}
-
-// RegisterShhService configures Whisper and adds it to the given node.
-func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
- if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
- return whisper.New(cfg), nil
- }); err != nil {
- Fatalf("Failed to register the Whisper service: %v", err)
- }
-}
-
-// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
-// th egiven node.
-func RegisterEthStatsService(stack *node.Node, url string) {
- if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- // Retrieve both eth and les services
- var ethServ *eth.Ethereum
- ctx.Service(ðServ)
-
- var lesServ *les.LightEthereum
- ctx.Service(&lesServ)
-
- return ethstats.New(url, ethServ, lesServ)
- }); err != nil {
- Fatalf("Failed to register the Ethereum Stats service: %v", err)
- }
}
// SetupNetwork configures the system for either the main net or some test network.
@@ -1221,7 +1202,7 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
if ctx.GlobalBool(LightModeFlag.Name) {
name = "lightchaindata"
}
- chainDb, err := stack.OpenDatabase(name, cache, handles)
+ chainDb, err := stack.OpenDatabase(name, cache, handles, "")
if err != nil {
Fatalf("Could not open database: %v", err)
}
@@ -1326,3 +1307,26 @@ func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error
return action(ctx)
}
}
+
+// find all filenames match the given pattern in the given root directory
+func WalkMatch(root, pattern string) ([]string, error) {
+ matches := []string{}
+ err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if info.IsDir() {
+ return nil
+ }
+ if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
+ return err
+ } else if matched {
+ matches = append(matches, path)
+ }
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return matches, nil
+}
diff --git a/cmd/utils/flags_test.go b/cmd/utils/flags_test.go
new file mode 100644
index 0000000000..5a7144043d
--- /dev/null
+++ b/cmd/utils/flags_test.go
@@ -0,0 +1,73 @@
+package utils
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+func TestWalkMatch(t *testing.T) {
+ type args struct {
+ root string
+ pattern string
+ }
+ dir, err := os.Getwd()
+ if err != nil {
+ log.Fatal(err)
+ }
+ test1Dir, _ := ioutil.TempDir(dir, "test1")
+ test2Dir, _ := ioutil.TempDir(dir, "test2")
+ err = ioutil.WriteFile(filepath.Join(test1Dir, "test1.ldb"), []byte("hello"), os.ModePerm)
+ if err != nil {
+ log.Fatal(err)
+ }
+ err = ioutil.WriteFile(filepath.Join(test2Dir, "test2.abc"), []byte("hello"), os.ModePerm)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer func() {
+ os.RemoveAll(test1Dir)
+ os.RemoveAll(test2Dir)
+ }()
+
+ tests := []struct {
+ name string
+ args args
+ want []string
+ wantErr bool
+ }{
+ {
+ "match test",
+ args{
+ root: test1Dir,
+ pattern: "*ldb",
+ },
+ []string{filepath.Join(test1Dir, "test1.ldb")},
+ false,
+ },
+ {
+ "mismatch test",
+ args{
+ root: test2Dir,
+ pattern: "*ldb",
+ },
+ []string{},
+ false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := WalkMatch(tt.args.root, tt.args.pattern)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("WalkMatch() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("WalkMatch() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/cmd/utils/utils.go b/cmd/utils/utils.go
new file mode 100644
index 0000000000..94d2eb387c
--- /dev/null
+++ b/cmd/utils/utils.go
@@ -0,0 +1,80 @@
+package utils
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending"
+ "github.com/XinFinOrg/XDPoSChain/eth"
+ "github.com/XinFinOrg/XDPoSChain/eth/downloader"
+ "github.com/XinFinOrg/XDPoSChain/ethstats"
+ "github.com/XinFinOrg/XDPoSChain/les"
+ "github.com/XinFinOrg/XDPoSChain/node"
+ whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6"
+)
+
+// RegisterEthService adds an Ethereum client to the stack.
+func RegisterEthService(stack *node.Node, cfg *eth.Config) {
+ var err error
+ if cfg.SyncMode == downloader.LightSync {
+ err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ return les.New(ctx, cfg)
+ })
+ } else {
+ err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ var XDCXServ *XDCx.XDCX
+ ctx.Service(&XDCXServ)
+ var lendingServ *XDCxlending.Lending
+ ctx.Service(&lendingServ)
+ fullNode, err := eth.New(ctx, cfg, XDCXServ, lendingServ)
+ if fullNode != nil && cfg.LightServ > 0 {
+ ls, _ := les.NewLesServer(fullNode, cfg)
+ fullNode.AddLesServer(ls)
+ }
+ return fullNode, err
+ })
+ }
+ if err != nil {
+ Fatalf("Failed to register the Ethereum service: %v", err)
+ }
+}
+
+// RegisterShhService configures Whisper and adds it to the given node.
+func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
+ if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
+ return whisper.New(cfg), nil
+ }); err != nil {
+ Fatalf("Failed to register the Whisper service: %v", err)
+ }
+}
+
+// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
+// th egiven node.
+func RegisterEthStatsService(stack *node.Node, url string) {
+ if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ // Retrieve both eth and les services
+ var ethServ *eth.Ethereum
+ ctx.Service(ðServ)
+
+ var lesServ *les.LightEthereum
+ ctx.Service(&lesServ)
+
+ return ethstats.New(url, ethServ, lesServ)
+ }); err != nil {
+ Fatalf("Failed to register the Ethereum Stats service: %v", err)
+ }
+}
+
+func RegisterXDCXService(stack *node.Node, cfg *XDCx.Config) {
+ XDCX := XDCx.New(cfg)
+ if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
+ return XDCX, nil
+ }); err != nil {
+ Fatalf("Failed to register the XDCX service: %v", err)
+ }
+
+ // register XDCxlending service
+ if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
+ return XDCxlending.New(XDCX), nil
+ }); err != nil {
+ Fatalf("Failed to register the XDCXLending service: %v", err)
+ }
+}
diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go
index 988c50ce3d..6af37d48ba 100644
--- a/cmd/wnode/main.go
+++ b/cmd/wnode/main.go
@@ -35,16 +35,16 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/whisper/mailserver"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
+ "github.com/XinFinOrg/XDPoSChain/cmd/utils"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/console"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/p2p"
+ "github.com/XinFinOrg/XDPoSChain/p2p/discover"
+ "github.com/XinFinOrg/XDPoSChain/p2p/nat"
+ "github.com/XinFinOrg/XDPoSChain/whisper/mailserver"
+ whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6"
"golang.org/x/crypto/pbkdf2"
)
diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go
index 9bd1de103a..19a3324e8b 100644
--- a/common/bitutil/compress_test.go
+++ b/common/bitutil/compress_test.go
@@ -21,7 +21,7 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
// Tests that data bitset encoding and decoding works and is bijective.
diff --git a/common/bytes.go b/common/bytes.go
index f143f150d8..79caa1f49c 100644
--- a/common/bytes.go
+++ b/common/bytes.go
@@ -28,8 +28,6 @@ func ToHex(b []byte) string {
return "0x" + hex
}
-// FromHex returns the bytes represented by the hexadecimal string s.
-// s may be prefixed with "0x".
func FromHex(s string) []byte {
if len(s) > 1 {
if s[0:2] == "0x" || s[0:2] == "0X" {
@@ -57,11 +55,9 @@ func CopyBytes(b []byte) (copiedBytes []byte) {
return
}
-
func hasXDCPrefix(str string) bool {
return len(str) >= 3 && (str[0] == 'x' || str[0] == 'X') && (str[1] == 'd' || str[1] == 'D') && (str[2] == 'c' || str[2] == 'C')
}
-
func hasHexPrefix(str string) bool {
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
}
diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go
index 0da3bb337e..20573d73ca 100644
--- a/common/compiler/solidity_test.go
+++ b/common/compiler/solidity_test.go
@@ -39,6 +39,7 @@ func skipWithoutSolc(t *testing.T) {
}
func TestCompiler(t *testing.T) {
+ t.SkipNow()
skipWithoutSolc(t)
contracts, err := CompileSolidityString("", testSource)
diff --git a/common/constants.go b/common/constants.go
index 900829a64c..daeac097d1 100644
--- a/common/constants.go
+++ b/common/constants.go
@@ -17,6 +17,7 @@ const (
MaxMasternodes = 18
MaxMasternodesV2 = 108
LimitPenaltyEpoch = 4
+ BlocksPerYearTest = uint64(200000)
BlocksPerYear = uint64(15768000)
LimitThresholdNonceInQueue = 10
DefaultMinGasPrice = 250000000
@@ -24,21 +25,55 @@ const (
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
IgnoreSignerCheckBlock = uint64(27307800)
+ OneYear = uint64(365 * 86400)
+ LiquidateLendingTradeBlock = uint64(100)
)
+var Rewound = uint64(0)
+
var TIP2019Block = big.NewInt(1)
var TIPSigning = big.NewInt(3000000)
var TIPRandomize = big.NewInt(3464000)
+
var TIPIncreaseMasternodes = big.NewInt(5000000) // Upgrade MN Count at Block.
-var BlackListHFNumber = uint64(9349100)
+var TIPNoHalvingMNReward = big.NewInt(40000000) // hardfork no halving masternodes reward
+var BlackListHFNumber = uint64(40000000)
+var TIPXDCX = big.NewInt(40000000)
+var TIPXDCXLending = big.NewInt(40000000)
+var TIPXDCXCancellationFee = big.NewInt(40000000)
+var TIPXDCXCancellationFeeTestnet = big.NewInt(23777777)
+
+var TIPXDCXTestnet = big.NewInt(23777777)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash
+var BasePrice = big.NewInt(1000000000000000000) // 1
+var RelayerLockedFund = big.NewInt(20000) // 20000 XDC
+var RelayerFee = big.NewInt(1000000000000000) // 0.001
+var XDCXBaseFee = big.NewInt(10000) // 1 / XDCXBaseFee
+var RelayerCancelFee = big.NewInt(100000000000000) // 0.0001
+var XDCXBaseCancelFee = new(big.Int).Mul(XDCXBaseFee, big.NewInt(10)) // 1/ (XDCXBaseFee *10)
+var RelayerLendingFee = big.NewInt(10000000000000000) // 0.01
+var RelayerLendingCancelFee = big.NewInt(1000000000000000) // 0.001
+var BaseLendingInterest = big.NewInt(100000000) // 1e8
+
var MinGasPrice = big.NewInt(DefaultMinGasPrice)
-var TRC21IssuerSMCTestNet = HexToAddress("0x7081C72c9DC44686C7B7EAB1d338EA137Fa9f0D3")
+var RelayerRegistrationSMC = "0x16c63b79f9C8784168103C0b74E6A59EC2de4a02"
+var RelayerRegistrationSMCTestnet = "0xA1996F69f47ba14Cb7f661010A7C31974277958c"
+var LendingRegistrationSMC = "0x7d761afd7ff65a79e4173897594a194e3c506e57"
+var LendingRegistrationSMCTestnet = "0x28d7fC2Cf5c18203aaCD7459EFC6Af0643C97bE8"
+var TRC21IssuerSMCTestNet = HexToAddress("0x0E2C88753131CE01c7551B726b28BFD04e44003F")
var TRC21IssuerSMC = HexToAddress("0x8c0faeb5C6bEd2129b8674F262Fd45c4e9468bee")
+var XDCXListingSMC = HexToAddress("0xDE34dD0f536170993E8CFF639DdFfCF1A85D3E53")
+var XDCXListingSMCTestNet = HexToAddress("0x14B2Bf043b9c31827A472CE4F94294fE9a6277e0")
var TRC21GasPriceBefore = big.NewInt(2500)
var TRC21GasPrice = big.NewInt(250000000)
+var RateTopUp = big.NewInt(90) // 90%
+var BaseTopUp = big.NewInt(100)
+var BaseRecall = big.NewInt(100)
+var TIPTRC21Fee = big.NewInt(40000000)
+var TIPTRC21FeeTestnet = big.NewInt(23777777)
+var LimitTimeFinality = uint64(30) // limit in 30 block
var Blacklist = map[Address]bool{
HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true,
HexToAddress("0x5ac26105b35ea8935be382863a70281ec7a985e9"): true,
@@ -100,5 +135,5 @@ var Blacklist = map[Address]bool{
HexToAddress("0xfe685f43acc62f92ab01a8da80d76455d39d3cb3"): true,
HexToAddress("0x3538a544021c07869c16b764424c5987409cba48"): true,
HexToAddress("0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"): true,
+ HexToAddress("0x0000000000000000000000000000000000000011"): true,
}
-var TIPTRC21Fee = big.NewInt(13523400)
diff --git a/common/debug.go b/common/debug.go
index 61acd8ce70..3ed8c1c796 100644
--- a/common/debug.go
+++ b/common/debug.go
@@ -26,7 +26,7 @@ import (
// Report gives off a warning requesting the user to submit an issue to the github tracker.
func Report(extra ...interface{}) {
- fmt.Fprintln(os.Stderr, "You've encountered a sought after, hard to reproduce bug. Please report this to the developers <3 https://github.com/ethereum/go-ethereum/issues")
+ fmt.Fprintln(os.Stderr, "You've encountered a sought after, hard to reproduce bug. Please report this to the developers <3 https://github.com/XinFinOrg/XDPoSChain/issues")
fmt.Fprintln(os.Stderr, extra...)
_, file, line, _ := runtime.Caller(1)
diff --git a/common/hexutil/json.go b/common/hexutil/json.go
index ac12ce14cf..2a1b06146a 100644
--- a/common/hexutil/json.go
+++ b/common/hexutil/json.go
@@ -288,7 +288,6 @@ func bytesHave0xPrefix(input []byte) bool {
func bytesHaveXDCPrefix(input []byte) bool {
return len(input) >= 3 && (input[0] == 'x' || input[0] == 'X') && (input[1] == 'd' || input[1] == 'D') && (input[2] == 'c' || input[2] == 'C')
}
-
func checkText(input []byte, wantPrefix bool) ([]byte, error) {
if len(input) == 0 {
return nil, nil // empty strings are allowed
@@ -296,7 +295,7 @@ func checkText(input []byte, wantPrefix bool) ([]byte, error) {
if bytesHaveXDCPrefix(input) {
input = input[3:]
} else if bytesHave0xPrefix(input) {
- input = input[2:]
+ input = input[2:]
} else if wantPrefix {
return nil, ErrMissingPrefix
}
diff --git a/common/hexutil/json_example_test.go b/common/hexutil/json_example_test.go
index 80180d9186..a368083284 100644
--- a/common/hexutil/json_example_test.go
+++ b/common/hexutil/json_example_test.go
@@ -20,7 +20,7 @@ import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
type MyType [5]byte
diff --git a/common/math/big_test.go b/common/math/big_test.go
index be9810dc8c..2c607bad5f 100644
--- a/common/math/big_test.go
+++ b/common/math/big_test.go
@@ -22,7 +22,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
func TestHexOrDecimal256(t *testing.T) {
diff --git a/common/mclock/mclock.go b/common/mclock/mclock.go
index 92005252eb..3aca257cb3 100644
--- a/common/mclock/mclock.go
+++ b/common/mclock/mclock.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-// package mclock is a wrapper for a monotonic clock source
+// Package mclock is a wrapper for a monotonic clock source
package mclock
import (
@@ -23,8 +23,101 @@ import (
"github.com/aristanetworks/goarista/monotime"
)
-type AbsTime time.Duration // absolute monotonic time
+// AbsTime represents absolute monotonic time.
+type AbsTime time.Duration
+// Now returns the current absolute monotonic time.
func Now() AbsTime {
return AbsTime(monotime.Now())
}
+
+// Add returns t + d as absolute time.
+func (t AbsTime) Add(d time.Duration) AbsTime {
+ return t + AbsTime(d)
+}
+
+// Sub returns t - t2 as a duration.
+func (t AbsTime) Sub(t2 AbsTime) time.Duration {
+ return time.Duration(t - t2)
+}
+
+// The Clock interface makes it possible to replace the monotonic system clock with
+// a simulated clock.
+type Clock interface {
+ Now() AbsTime
+ Sleep(time.Duration)
+ NewTimer(time.Duration) ChanTimer
+ After(time.Duration) <-chan AbsTime
+ AfterFunc(d time.Duration, f func()) Timer
+}
+
+// Timer is a cancellable event created by AfterFunc.
+type Timer interface {
+ // Stop cancels the timer. It returns false if the timer has already
+ // expired or been stopped.
+ Stop() bool
+}
+
+// ChanTimer is a cancellable event created by NewTimer.
+type ChanTimer interface {
+ Timer
+
+ // The channel returned by C receives a value when the timer expires.
+ C() <-chan AbsTime
+ // Reset reschedules the timer with a new timeout.
+ // It should be invoked only on stopped or expired timers with drained channels.
+ Reset(time.Duration)
+}
+
+// System implements Clock using the system clock.
+type System struct{}
+
+// Now returns the current monotonic time.
+func (c System) Now() AbsTime {
+ return AbsTime(monotime.Now())
+}
+
+// Sleep blocks for the given duration.
+func (c System) Sleep(d time.Duration) {
+ time.Sleep(d)
+}
+
+// NewTimer creates a timer which can be rescheduled.
+func (c System) NewTimer(d time.Duration) ChanTimer {
+ ch := make(chan AbsTime, 1)
+ t := time.AfterFunc(d, func() {
+ // This send is non-blocking because that's how time.Timer
+ // behaves. It doesn't matter in the happy case, but does
+ // when Reset is misused.
+ select {
+ case ch <- c.Now():
+ default:
+ }
+ })
+ return &systemTimer{t, ch}
+}
+
+// After returns a channel which receives the current time after d has elapsed.
+func (c System) After(d time.Duration) <-chan AbsTime {
+ ch := make(chan AbsTime, 1)
+ time.AfterFunc(d, func() { ch <- c.Now() })
+ return ch
+}
+
+// AfterFunc runs f on a new goroutine after the duration has elapsed.
+func (c System) AfterFunc(d time.Duration, f func()) Timer {
+ return time.AfterFunc(d, f)
+}
+
+type systemTimer struct {
+ *time.Timer
+ ch <-chan AbsTime
+}
+
+func (st *systemTimer) Reset(d time.Duration) {
+ st.Timer.Reset(d)
+}
+
+func (st *systemTimer) C() <-chan AbsTime {
+ return st.ch
+}
diff --git a/common/mclock/simclock.go b/common/mclock/simclock.go
new file mode 100644
index 0000000000..766ca0f873
--- /dev/null
+++ b/common/mclock/simclock.go
@@ -0,0 +1,209 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package mclock
+
+import (
+ "container/heap"
+ "sync"
+ "time"
+)
+
+// Simulated implements a virtual Clock for reproducible time-sensitive tests. It
+// simulates a scheduler on a virtual timescale where actual processing takes zero time.
+//
+// The virtual clock doesn't advance on its own, call Run to advance it and execute timers.
+// Since there is no way to influence the Go scheduler, testing timeout behaviour involving
+// goroutines needs special care. A good way to test such timeouts is as follows: First
+// perform the action that is supposed to time out. Ensure that the timer you want to test
+// is created. Then run the clock until after the timeout. Finally observe the effect of
+// the timeout using a channel or semaphore.
+type Simulated struct {
+ now AbsTime
+ scheduled simTimerHeap
+ mu sync.RWMutex
+ cond *sync.Cond
+}
+
+// simTimer implements ChanTimer on the virtual clock.
+type simTimer struct {
+ at AbsTime
+ index int // position in s.scheduled
+ s *Simulated
+ do func()
+ ch <-chan AbsTime
+}
+
+func (s *Simulated) init() {
+ if s.cond == nil {
+ s.cond = sync.NewCond(&s.mu)
+ }
+}
+
+// Run moves the clock by the given duration, executing all timers before that duration.
+func (s *Simulated) Run(d time.Duration) {
+ s.mu.Lock()
+ s.init()
+
+ end := s.now + AbsTime(d)
+ var do []func()
+ for len(s.scheduled) > 0 && s.scheduled[0].at <= end {
+ ev := heap.Pop(&s.scheduled).(*simTimer)
+ do = append(do, ev.do)
+ }
+ s.now = end
+ s.mu.Unlock()
+
+ for _, fn := range do {
+ fn()
+ }
+}
+
+// ActiveTimers returns the number of timers that haven't fired.
+func (s *Simulated) ActiveTimers() int {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+
+ return len(s.scheduled)
+}
+
+// WaitForTimers waits until the clock has at least n scheduled timers.
+func (s *Simulated) WaitForTimers(n int) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.init()
+
+ for len(s.scheduled) < n {
+ s.cond.Wait()
+ }
+}
+
+// Now returns the current virtual time.
+func (s *Simulated) Now() AbsTime {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+
+ return s.now
+}
+
+// Sleep blocks until the clock has advanced by d.
+func (s *Simulated) Sleep(d time.Duration) {
+ <-s.After(d)
+}
+
+// NewTimer creates a timer which fires when the clock has advanced by d.
+func (s *Simulated) NewTimer(d time.Duration) ChanTimer {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ ch := make(chan AbsTime, 1)
+ var timer *simTimer
+ timer = s.schedule(d, func() { ch <- timer.at })
+ timer.ch = ch
+ return timer
+}
+
+// After returns a channel which receives the current time after the clock
+// has advanced by d.
+func (s *Simulated) After(d time.Duration) <-chan AbsTime {
+ return s.NewTimer(d).C()
+}
+
+// AfterFunc runs fn after the clock has advanced by d. Unlike with the system
+// clock, fn runs on the goroutine that calls Run.
+func (s *Simulated) AfterFunc(d time.Duration, fn func()) Timer {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ return s.schedule(d, fn)
+}
+
+func (s *Simulated) schedule(d time.Duration, fn func()) *simTimer {
+ s.init()
+
+ at := s.now + AbsTime(d)
+ ev := &simTimer{do: fn, at: at, s: s}
+ heap.Push(&s.scheduled, ev)
+ s.cond.Broadcast()
+ return ev
+}
+
+func (ev *simTimer) Stop() bool {
+ ev.s.mu.Lock()
+ defer ev.s.mu.Unlock()
+
+ if ev.index < 0 {
+ return false
+ }
+ heap.Remove(&ev.s.scheduled, ev.index)
+ ev.s.cond.Broadcast()
+ ev.index = -1
+ return true
+}
+
+func (ev *simTimer) Reset(d time.Duration) {
+ if ev.ch == nil {
+ panic("mclock: Reset() on timer created by AfterFunc")
+ }
+
+ ev.s.mu.Lock()
+ defer ev.s.mu.Unlock()
+ ev.at = ev.s.now.Add(d)
+ if ev.index < 0 {
+ heap.Push(&ev.s.scheduled, ev) // already expired
+ } else {
+ heap.Fix(&ev.s.scheduled, ev.index) // hasn't fired yet, reschedule
+ }
+ ev.s.cond.Broadcast()
+}
+
+func (ev *simTimer) C() <-chan AbsTime {
+ if ev.ch == nil {
+ panic("mclock: C() on timer created by AfterFunc")
+ }
+ return ev.ch
+}
+
+type simTimerHeap []*simTimer
+
+func (h *simTimerHeap) Len() int {
+ return len(*h)
+}
+
+func (h *simTimerHeap) Less(i, j int) bool {
+ return (*h)[i].at < (*h)[j].at
+}
+
+func (h *simTimerHeap) Swap(i, j int) {
+ (*h)[i], (*h)[j] = (*h)[j], (*h)[i]
+ (*h)[i].index = i
+ (*h)[j].index = j
+}
+
+func (h *simTimerHeap) Push(x interface{}) {
+ t := x.(*simTimer)
+ t.index = len(*h)
+ *h = append(*h, t)
+}
+
+func (h *simTimerHeap) Pop() interface{} {
+ end := len(*h) - 1
+ t := (*h)[end]
+ t.index = -1
+ (*h)[end] = nil
+ *h = (*h)[:end]
+ return t
+}
diff --git a/common/mclock/simclock_test.go b/common/mclock/simclock_test.go
new file mode 100644
index 0000000000..48f3fd56a0
--- /dev/null
+++ b/common/mclock/simclock_test.go
@@ -0,0 +1,162 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package mclock
+
+import (
+ "testing"
+ "time"
+)
+
+var _ Clock = System{}
+var _ Clock = new(Simulated)
+
+func TestSimulatedAfter(t *testing.T) {
+ var (
+ timeout = 30 * time.Minute
+ offset = 99 * time.Hour
+ adv = 11 * time.Minute
+ c Simulated
+ )
+ c.Run(offset)
+
+ end := c.Now().Add(timeout)
+ ch := c.After(timeout)
+ for c.Now() < end.Add(-adv) {
+ c.Run(adv)
+ select {
+ case <-ch:
+ t.Fatal("Timer fired early")
+ default:
+ }
+ }
+
+ c.Run(adv)
+ select {
+ case stamp := <-ch:
+ want := AbsTime(0).Add(offset).Add(timeout)
+ if stamp != want {
+ t.Errorf("Wrong time sent on timer channel: got %v, want %v", stamp, want)
+ }
+ default:
+ t.Fatal("Timer didn't fire")
+ }
+}
+
+func TestSimulatedAfterFunc(t *testing.T) {
+ var c Simulated
+
+ called1 := false
+ timer1 := c.AfterFunc(100*time.Millisecond, func() { called1 = true })
+ if c.ActiveTimers() != 1 {
+ t.Fatalf("%d active timers, want one", c.ActiveTimers())
+ }
+ if fired := timer1.Stop(); !fired {
+ t.Fatal("Stop returned false even though timer didn't fire")
+ }
+ if c.ActiveTimers() != 0 {
+ t.Fatalf("%d active timers, want zero", c.ActiveTimers())
+ }
+ if called1 {
+ t.Fatal("timer 1 called")
+ }
+ if fired := timer1.Stop(); fired {
+ t.Fatal("Stop returned true after timer was already stopped")
+ }
+
+ called2 := false
+ timer2 := c.AfterFunc(100*time.Millisecond, func() { called2 = true })
+ c.Run(50 * time.Millisecond)
+ if called2 {
+ t.Fatal("timer 2 called")
+ }
+ c.Run(51 * time.Millisecond)
+ if !called2 {
+ t.Fatal("timer 2 not called")
+ }
+ if fired := timer2.Stop(); fired {
+ t.Fatal("Stop returned true after timer has fired")
+ }
+}
+
+func TestSimulatedSleep(t *testing.T) {
+ var (
+ c Simulated
+ timeout = 1 * time.Hour
+ done = make(chan AbsTime, 1)
+ )
+ go func() {
+ c.Sleep(timeout)
+ done <- c.Now()
+ }()
+
+ c.WaitForTimers(1)
+ c.Run(2 * timeout)
+ select {
+ case stamp := <-done:
+ want := AbsTime(2 * timeout)
+ if stamp != want {
+ t.Errorf("Wrong time after sleep: got %v, want %v", stamp, want)
+ }
+ case <-time.After(5 * time.Second):
+ t.Fatal("Sleep didn't return in time")
+ }
+}
+
+func TestSimulatedTimerReset(t *testing.T) {
+ var (
+ c Simulated
+ timeout = 1 * time.Hour
+ )
+ timer := c.NewTimer(timeout)
+ c.Run(2 * timeout)
+ select {
+ case ftime := <-timer.C():
+ if ftime != AbsTime(timeout) {
+ t.Fatalf("wrong time %v sent on timer channel, want %v", ftime, AbsTime(timeout))
+ }
+ default:
+ t.Fatal("timer didn't fire")
+ }
+
+ timer.Reset(timeout)
+ c.Run(2 * timeout)
+ select {
+ case ftime := <-timer.C():
+ if ftime != AbsTime(3*timeout) {
+ t.Fatalf("wrong time %v sent on timer channel, want %v", ftime, AbsTime(3*timeout))
+ }
+ default:
+ t.Fatal("timer didn't fire again")
+ }
+}
+
+func TestSimulatedTimerStop(t *testing.T) {
+ var (
+ c Simulated
+ timeout = 1 * time.Hour
+ )
+ timer := c.NewTimer(timeout)
+ c.Run(2 * timeout)
+ if timer.Stop() {
+ t.Errorf("Stop returned true for fired timer")
+ }
+ select {
+ case <-timer.C():
+ default:
+ t.Fatal("timer didn't fire")
+ }
+}
diff --git a/common/number/int.go b/common/number/int.go
index 6dab2436de..7a4f9f8ca1 100644
--- a/common/number/int.go
+++ b/common/number/int.go
@@ -19,7 +19,7 @@ package number
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
var tt256 = new(big.Int).Lsh(big.NewInt(1), 256)
diff --git a/common/number/uint_test.go b/common/number/uint_test.go
index 3ab9e4c344..8f4c5726a2 100644
--- a/common/number/uint_test.go
+++ b/common/number/uint_test.go
@@ -20,7 +20,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
func TestSet(t *testing.T) {
diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go
new file mode 100644
index 0000000000..035b8ff9e7
--- /dev/null
+++ b/common/prque/lazyqueue.go
@@ -0,0 +1,182 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package prque
+
+import (
+ "container/heap"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/common/mclock"
+)
+
+// LazyQueue is a priority queue data structure where priorities can change over
+// time and are only evaluated on demand.
+// Two callbacks are required:
+// - priority evaluates the actual priority of an item
+// - maxPriority gives an upper estimate for the priority in any moment between
+// now and the given absolute time
+// If the upper estimate is exceeded then Update should be called for that item.
+// A global Refresh function should also be called periodically.
+type LazyQueue struct {
+ clock mclock.Clock
+ // Items are stored in one of two internal queues ordered by estimated max
+ // priority until the next and the next-after-next refresh. Update and Refresh
+ // always places items in queue[1].
+ queue [2]*sstack
+ popQueue *sstack
+ period time.Duration
+ maxUntil mclock.AbsTime
+ indexOffset int
+ setIndex SetIndexCallback
+ priority PriorityCallback
+ maxPriority MaxPriorityCallback
+}
+
+type (
+ PriorityCallback func(data interface{}, now mclock.AbsTime) int64 // actual priority callback
+ MaxPriorityCallback func(data interface{}, until mclock.AbsTime) int64 // estimated maximum priority callback
+)
+
+// NewLazyQueue creates a new lazy queue
+func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPriority MaxPriorityCallback, clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue {
+ q := &LazyQueue{
+ popQueue: newSstack(nil),
+ setIndex: setIndex,
+ priority: priority,
+ maxPriority: maxPriority,
+ clock: clock,
+ period: refreshPeriod}
+ q.Reset()
+ q.Refresh()
+ return q
+}
+
+// Reset clears the contents of the queue
+func (q *LazyQueue) Reset() {
+ q.queue[0] = newSstack(q.setIndex0)
+ q.queue[1] = newSstack(q.setIndex1)
+}
+
+// Refresh should be called at least with the frequency specified by the refreshPeriod parameter
+func (q *LazyQueue) Refresh() {
+ q.maxUntil = q.clock.Now() + mclock.AbsTime(q.period)
+ for q.queue[0].Len() != 0 {
+ q.Push(heap.Pop(q.queue[0]).(*item).value)
+ }
+ q.queue[0], q.queue[1] = q.queue[1], q.queue[0]
+ q.indexOffset = 1 - q.indexOffset
+ q.maxUntil += mclock.AbsTime(q.period)
+}
+
+// Push adds an item to the queue
+func (q *LazyQueue) Push(data interface{}) {
+ heap.Push(q.queue[1], &item{data, q.maxPriority(data, q.maxUntil)})
+}
+
+// Update updates the upper priority estimate for the item with the given queue index
+func (q *LazyQueue) Update(index int) {
+ q.Push(q.Remove(index))
+}
+
+// Pop removes and returns the item with the greatest actual priority
+func (q *LazyQueue) Pop() (interface{}, int64) {
+ var (
+ resData interface{}
+ resPri int64
+ )
+ q.MultiPop(func(data interface{}, priority int64) bool {
+ resData = data
+ resPri = priority
+ return false
+ })
+ return resData, resPri
+}
+
+// peekIndex returns the index of the internal queue where the item with the
+// highest estimated priority is or -1 if both are empty
+func (q *LazyQueue) peekIndex() int {
+ if q.queue[0].Len() != 0 {
+ if q.queue[1].Len() != 0 && q.queue[1].blocks[0][0].priority > q.queue[0].blocks[0][0].priority {
+ return 1
+ }
+ return 0
+ }
+ if q.queue[1].Len() != 0 {
+ return 1
+ }
+ return -1
+}
+
+// MultiPop pops multiple items from the queue and is more efficient than calling
+// Pop multiple times. Popped items are passed to the callback. MultiPop returns
+// when the callback returns false or there are no more items to pop.
+func (q *LazyQueue) MultiPop(callback func(data interface{}, priority int64) bool) {
+ now := q.clock.Now()
+ nextIndex := q.peekIndex()
+ for nextIndex != -1 {
+ data := heap.Pop(q.queue[nextIndex]).(*item).value
+ heap.Push(q.popQueue, &item{data, q.priority(data, now)})
+ nextIndex = q.peekIndex()
+ for q.popQueue.Len() != 0 && (nextIndex == -1 || q.queue[nextIndex].blocks[0][0].priority < q.popQueue.blocks[0][0].priority) {
+ i := heap.Pop(q.popQueue).(*item)
+ if !callback(i.value, i.priority) {
+ for q.popQueue.Len() != 0 {
+ q.Push(heap.Pop(q.popQueue).(*item).value)
+ }
+ return
+ }
+ }
+ }
+}
+
+// PopItem pops the item from the queue only, dropping the associated priority value.
+func (q *LazyQueue) PopItem() interface{} {
+ i, _ := q.Pop()
+ return i
+}
+
+// Remove removes removes the item with the given index.
+func (q *LazyQueue) Remove(index int) interface{} {
+ if index < 0 {
+ return nil
+ }
+ return heap.Remove(q.queue[index&1^q.indexOffset], index>>1).(*item).value
+}
+
+// Empty checks whether the priority queue is empty.
+func (q *LazyQueue) Empty() bool {
+ return q.queue[0].Len() == 0 && q.queue[1].Len() == 0
+}
+
+// Size returns the number of items in the priority queue.
+func (q *LazyQueue) Size() int {
+ return q.queue[0].Len() + q.queue[1].Len()
+}
+
+// setIndex0 translates internal queue item index to the virtual index space of LazyQueue
+func (q *LazyQueue) setIndex0(data interface{}, index int) {
+ if index == -1 {
+ q.setIndex(data, -1)
+ } else {
+ q.setIndex(data, index+index)
+ }
+}
+
+// setIndex1 translates internal queue item index to the virtual index space of LazyQueue
+func (q *LazyQueue) setIndex1(data interface{}, index int) {
+ q.setIndex(data, index+index+1)
+}
diff --git a/common/prque/lazyqueue_test.go b/common/prque/lazyqueue_test.go
new file mode 100644
index 0000000000..bb43bd06d7
--- /dev/null
+++ b/common/prque/lazyqueue_test.go
@@ -0,0 +1,124 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package prque
+
+import (
+ "math/rand"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/common/mclock"
+)
+
+const (
+ testItems = 1000
+ testPriorityStep = 100
+ testSteps = 1000000
+ testStepPeriod = time.Millisecond
+ testQueueRefresh = time.Second
+ testAvgRate = float64(testPriorityStep) / float64(testItems) / float64(testStepPeriod)
+)
+
+type lazyItem struct {
+ p, maxp int64
+ last mclock.AbsTime
+ index int
+}
+
+func testPriority(a interface{}, now mclock.AbsTime) int64 {
+ return a.(*lazyItem).p
+}
+
+func testMaxPriority(a interface{}, until mclock.AbsTime) int64 {
+ i := a.(*lazyItem)
+ dt := until - i.last
+ i.maxp = i.p + int64(float64(dt)*testAvgRate)
+ return i.maxp
+}
+
+func testSetIndex(a interface{}, i int) {
+ a.(*lazyItem).index = i
+}
+
+func TestLazyQueue(t *testing.T) {
+ rand.Seed(time.Now().UnixNano())
+ clock := &mclock.Simulated{}
+ q := NewLazyQueue(testSetIndex, testPriority, testMaxPriority, clock, testQueueRefresh)
+
+ var (
+ items [testItems]lazyItem
+ maxPri int64
+ )
+
+ for i := range items[:] {
+ items[i].p = rand.Int63n(testPriorityStep * 10)
+ if items[i].p > maxPri {
+ maxPri = items[i].p
+ }
+ items[i].index = -1
+ q.Push(&items[i])
+ }
+
+ var (
+ lock sync.Mutex
+ wg sync.WaitGroup
+ stopCh = make(chan chan struct{})
+ )
+ defer wg.Wait()
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for {
+ select {
+ case <-clock.After(testQueueRefresh):
+ lock.Lock()
+ q.Refresh()
+ lock.Unlock()
+ case <-stopCh:
+ return
+ }
+ }
+ }()
+
+ for c := 0; c < testSteps; c++ {
+ i := rand.Intn(testItems)
+ lock.Lock()
+ items[i].p += rand.Int63n(testPriorityStep*2-1) + 1
+ if items[i].p > maxPri {
+ maxPri = items[i].p
+ }
+ items[i].last = clock.Now()
+ if items[i].p > items[i].maxp {
+ q.Update(items[i].index)
+ }
+ if rand.Intn(100) == 0 {
+ p := q.PopItem().(*lazyItem)
+ if p.p != maxPri {
+ lock.Unlock()
+ close(stopCh)
+ t.Fatalf("incorrect item (best known priority %d, popped %d)", maxPri, p.p)
+ }
+ q.Push(p)
+ }
+ lock.Unlock()
+ clock.Run(testStepPeriod)
+ clock.WaitForTimers(1)
+ }
+
+ close(stopCh)
+}
diff --git a/vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque.go b/common/prque/prque.go
similarity index 67%
rename from vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque.go
rename to common/prque/prque.go
index 5c1967c658..3cc5a1adaf 100755
--- a/vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque.go
+++ b/common/prque/prque.go
@@ -6,12 +6,10 @@
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
+// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque".
+
// Package prque implements a priority queue data structure supporting arbitrary
-// value types and float priorities.
-//
-// The reasoning behind using floats for the priorities vs. ints or interfaces
-// was larger flexibility without sacrificing too much performance or code
-// complexity.
+// value types and int64 priorities.
//
// If you would like to use a min-priority queue, simply negate the priorities.
//
@@ -28,19 +26,25 @@ type Prque struct {
cont *sstack
}
-// Creates a new priority queue.
-func New() *Prque {
- return &Prque{newSstack()}
+// New creates a new priority queue.
+func New(setIndex SetIndexCallback) *Prque {
+ return &Prque{newSstack(setIndex)}
}
// Pushes a value with a given priority into the queue, expanding if necessary.
-func (p *Prque) Push(data interface{}, priority float32) {
+func (p *Prque) Push(data interface{}, priority int64) {
heap.Push(p.cont, &item{data, priority})
}
+// Peek returns the value with the greates priority but does not pop it off.
+func (p *Prque) Peek() (interface{}, int64) {
+ item := p.cont.blocks[0][0]
+ return item.value, item.priority
+}
+
// Pops the value with the greates priority off the stack and returns it.
// Currently no shrinking is done.
-func (p *Prque) Pop() (interface{}, float32) {
+func (p *Prque) Pop() (interface{}, int64) {
item := heap.Pop(p.cont).(*item)
return item.value, item.priority
}
@@ -50,6 +54,14 @@ func (p *Prque) PopItem() interface{} {
return heap.Pop(p.cont).(*item).value
}
+// Remove removes the element with the given index.
+func (p *Prque) Remove(i int) interface{} {
+ if i < 0 {
+ return nil
+ }
+ return heap.Remove(p.cont, i)
+}
+
// Checks whether the priority queue is empty.
func (p *Prque) Empty() bool {
return p.cont.Len() == 0
@@ -62,5 +74,5 @@ func (p *Prque) Size() int {
// Clears the contents of the priority queue.
func (p *Prque) Reset() {
- *p = *New()
+ *p = *New(p.cont.setIndex)
}
diff --git a/vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack.go b/common/prque/sstack.go
similarity index 66%
rename from vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack.go
rename to common/prque/sstack.go
index 9f393196ef..8518af54ff 100755
--- a/vendor/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack.go
+++ b/common/prque/sstack.go
@@ -6,21 +6,32 @@
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
+// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque".
+
package prque
// The size of a block of data
const blockSize = 4096
// A prioritized item in the sorted stack.
+//
+// Note: priorities can "wrap around" the int64 range, a comes before b if (a.priority - b.priority) > 0.
+// The difference between the lowest and highest priorities in the queue at any point should be less than 2^63.
type item struct {
value interface{}
- priority float32
+ priority int64
}
+// SetIndexCallback is called when the element is moved to a new index.
+// Providing SetIndexCallback is optional, it is needed only if the application needs
+// to delete elements other than the top one.
+type SetIndexCallback func(data interface{}, index int)
+
// Internal sortable stack data structure. Implements the Push and Pop ops for
// the stack (heap) functionality and the Len, Less and Swap methods for the
// sortability requirements of the heaps.
type sstack struct {
+ setIndex SetIndexCallback
size int
capacity int
offset int
@@ -30,8 +41,9 @@ type sstack struct {
}
// Creates a new, empty stack.
-func newSstack() *sstack {
+func newSstack(setIndex SetIndexCallback) *sstack {
result := new(sstack)
+ result.setIndex = setIndex
result.active = make([]*item, blockSize)
result.blocks = [][]*item{result.active}
result.capacity = blockSize
@@ -50,6 +62,9 @@ func (s *sstack) Push(data interface{}) {
s.active = s.blocks[s.size/blockSize]
s.offset = 0
}
+ if s.setIndex != nil {
+ s.setIndex(data.(*item).value, s.size)
+ }
s.active[s.offset] = data.(*item)
s.offset++
s.size++
@@ -65,6 +80,9 @@ func (s *sstack) Pop() (res interface{}) {
s.active = s.blocks[s.size/blockSize]
}
res, s.active[s.offset] = s.active[s.offset], nil
+ if s.setIndex != nil {
+ s.setIndex(res.(*item).value, -1)
+ }
return
}
@@ -76,16 +94,21 @@ func (s *sstack) Len() int {
// Compares the priority of two elements of the stack (higher is first).
// Required by sort.Interface.
func (s *sstack) Less(i, j int) bool {
- return s.blocks[i/blockSize][i%blockSize].priority > s.blocks[j/blockSize][j%blockSize].priority
+ return (s.blocks[i/blockSize][i%blockSize].priority - s.blocks[j/blockSize][j%blockSize].priority) > 0
}
// Swaps two elements in the stack. Required by sort.Interface.
func (s *sstack) Swap(i, j int) {
ib, io, jb, jo := i/blockSize, i%blockSize, j/blockSize, j%blockSize
- s.blocks[ib][io], s.blocks[jb][jo] = s.blocks[jb][jo], s.blocks[ib][io]
+ a, b := s.blocks[jb][jo], s.blocks[ib][io]
+ if s.setIndex != nil {
+ s.setIndex(a.value, i)
+ s.setIndex(b.value, j)
+ }
+ s.blocks[ib][io], s.blocks[jb][jo] = a, b
}
// Resets the stack, effectively clearing its contents.
func (s *sstack) Reset() {
- *s = *newSstack()
+ *s = *newSstack(s.setIndex)
}
diff --git a/common/types.go b/common/types.go
index 91b1ba550b..dc1e1d6713 100644
--- a/common/types.go
+++ b/common/types.go
@@ -23,23 +23,31 @@ import (
"math/rand"
"reflect"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
)
const (
- HashLength = 32
- AddressLength = 20
- BlockSigners = "xdc0000000000000000000000000000000000000089"
- MasternodeVotingSMC = "xdc0000000000000000000000000000000000000088"
- RandomizeSMC = "xdc0000000000000000000000000000000000000090"
- FoudationAddr = "xdc746249C61f5832C5eEd53172776b460491bDcd5C"
- TeamAddr = "xdc0000000000000000000000000000000000000099"
- VoteMethod = "0x6dd7d8ea"
- UnvoteMethod = "0x02aa9be2"
- ProposeMethod = "0x01267951"
- ResignMethod = "0xae6e43f5"
- SignMethod = "0xe341eaa4"
+ HashLength = 32
+ AddressLength = 20
+ BlockSigners = "xdc0000000000000000000000000000000000000089"
+ MasternodeVotingSMC = "xdc0000000000000000000000000000000000000088"
+ RandomizeSMC = "xdc0000000000000000000000000000000000000090"
+ FoudationAddr = "xdc0000000000000000000000000000000000000068"
+ TeamAddr = "xdc0000000000000000000000000000000000000099"
+ XDCXAddr = "xdc0000000000000000000000000000000000000091"
+ TradingStateAddr = "xdc0000000000000000000000000000000000000092"
+ XDCXLendingAddress = "xdc0000000000000000000000000000000000000093"
+ XDCXLendingFinalizedTradeAddress = "xdc0000000000000000000000000000000000000094"
+ XDCNativeAddress = "xdc0000000000000000000000000000000000000001"
+ LendingLockAddress = "xdc0000000000000000000000000000000000000011"
+ VoteMethod = "0x6dd7d8ea"
+ UnvoteMethod = "0x02aa9be2"
+ ProposeMethod = "0x01267951"
+ ResignMethod = "0xae6e43f5"
+ SignMethod = "0xe341eaa4"
+ XDCXApplyMethod = "0xc6b32f34"
+ XDCZApplyMethod = "0xc6b32f34"
)
var (
@@ -62,6 +70,7 @@ func BytesToHash(b []byte) Hash {
}
func StringToHash(s string) Hash { return BytesToHash([]byte(s)) }
func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
+func Uint64ToHash(b uint64) Hash { return BytesToHash(new(big.Int).SetUint64(b).Bytes()) }
func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
// Get the string representation of the underlying hash
@@ -233,7 +242,7 @@ func (a *Address) Set(other Address) {
// MarshalText returns the hex representation of a.
func (a Address) MarshalText() ([]byte, error) {
- return hexutil.Bytes(a[:]).MarshalXDCText()
+ return hexutil.Bytes(a[:]).MarshalText()
}
// UnmarshalText parses a hash in hex syntax.
diff --git a/common/types_test.go b/common/types_test.go
index 0c47b79e54..d7d310576d 100644
--- a/common/types_test.go
+++ b/common/types_test.go
@@ -149,7 +149,7 @@ func TestAddressHexChecksum(t *testing.T) {
}
func BenchmarkAddressHex(b *testing.B) {
- testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
+ testAddr := HexToAddress("0xdc5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
for n := 0; n < b.N; n++ {
testAddr.Hex()
}
diff --git a/compression/rle/read_write.go b/compression/rle/read_write.go
index 0e7ad90aec..d5aadf8c1d 100644
--- a/compression/rle/read_write.go
+++ b/compression/rle/read_write.go
@@ -21,7 +21,7 @@ import (
"bytes"
"errors"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
const (
diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go
index e7979626b4..b54902a6a1 100644
--- a/consensus/XDPoS/XDPoS.go
+++ b/consensus/XDPoS/XDPoS.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -31,21 +31,25 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
+ "gopkg.in/karalabe/cookiejar.v2/collections/prque"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/clique"
+ "github.com/XinFinOrg/XDPoSChain/consensus/misc"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
lru "github.com/hashicorp/golang-lru"
)
@@ -60,6 +64,35 @@ type Masternode struct {
Stake *big.Int
}
+type TradingService interface {
+ GetTradingStateRoot(block *types.Block, author common.Address) (common.Hash, error)
+ GetTradingState(block *types.Block, author common.Address) (*tradingstate.TradingStateDB, error)
+ HasTradingState(block *types.Block, author common.Address) bool
+ GetStateCache() tradingstate.Database
+ GetTriegc() *prque.Prque
+ ApplyOrder(header *types.Header, coinbase common.Address, chain consensus.ChainContext, statedb *state.StateDB, XDCXstatedb *tradingstate.TradingStateDB, orderBook common.Hash, order *tradingstate.OrderItem) ([]map[string]string, []*tradingstate.OrderItem, error)
+ UpdateMediumPriceBeforeEpoch(epochNumber uint64, tradingStateDB *tradingstate.TradingStateDB, statedb *state.StateDB) error
+ IsSDKNode() bool
+ SyncDataToSDKNode(takerOrder *tradingstate.OrderItem, txHash common.Hash, txMatchTime time.Time, statedb *state.StateDB, trades []map[string]string, rejectedOrders []*tradingstate.OrderItem, dirtyOrderCount *uint64) error
+ RollbackReorgTxMatch(txhash common.Hash) error
+ GetTokenDecimal(chain consensus.ChainContext, statedb *state.StateDB, tokenAddr common.Address) (*big.Int, error)
+}
+
+type LendingService interface {
+ GetLendingStateRoot(block *types.Block, author common.Address) (common.Hash, error)
+ GetLendingState(block *types.Block, author common.Address) (*lendingstate.LendingStateDB, error)
+ HasLendingState(block *types.Block, author common.Address) bool
+ GetStateCache() lendingstate.Database
+ GetTriegc() *prque.Prque
+ ApplyOrder(header *types.Header, coinbase common.Address, chain consensus.ChainContext, statedb *state.StateDB, lendingStateDB *lendingstate.LendingStateDB, tradingStateDb *tradingstate.TradingStateDB, lendingOrderBook common.Hash, order *lendingstate.LendingItem) ([]*lendingstate.LendingTrade, []*lendingstate.LendingItem, error)
+ GetCollateralPrices(header *types.Header, chain consensus.ChainContext, statedb *state.StateDB, tradingStateDb *tradingstate.TradingStateDB, collateralToken common.Address, lendingToken common.Address) (*big.Int, *big.Int, error)
+ GetMediumTradePriceBeforeEpoch(chain consensus.ChainContext, statedb *state.StateDB, tradingStateDb *tradingstate.TradingStateDB, baseToken common.Address, quoteToken common.Address) (*big.Int, error)
+ ProcessLiquidationData(header *types.Header, chain consensus.ChainContext, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (updatedTrades map[common.Hash]*lendingstate.LendingTrade, liquidatedTrades, autoRepayTrades, autoTopUpTrades, autoRecallTrades []*lendingstate.LendingTrade, err error)
+ SyncDataToSDKNode(chain consensus.ChainContext, state *state.StateDB, block *types.Block, takerOrderInTx *lendingstate.LendingItem, txHash common.Hash, txMatchTime time.Time, trades []*lendingstate.LendingTrade, rejectedOrders []*lendingstate.LendingItem, dirtyOrderCount *uint64) error
+ UpdateLiquidatedTrade(blockTime uint64, result lendingstate.FinalizedResult, trades map[common.Hash]*lendingstate.LendingTrade) error
+ RollbackLendingData(txhash common.Hash) error
+}
+
// XDPoS delegated-proof-of-stake protocol constants.
var (
epochLength = uint64(900) // Default number of blocks after which to checkpoint and reset the pending votes
@@ -228,12 +261,14 @@ type XDPoS struct {
lock sync.RWMutex // Protects the signer fields
BlockSigners *lru.Cache
- HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{})
+ HookReward func(chain consensus.ChainReader, state *state.StateDB, parentState *state.StateDB, header *types.Header) (error, map[string]interface{})
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
- HookGetSignersFromContract func(blockHash common.Hash) ([]common.Address, error)
HookPenaltyTIPSigning func(chain consensus.ChainReader, header *types.Header, candidate []common.Address) ([]common.Address, error)
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(header *types.Header, signers []common.Address) error
+ GetXDCXService func() TradingService
+ GetLendingService func() LendingService
+ HookGetSignersFromContract func(blockHash common.Hash) ([]common.Address, error)
}
// New creates a XDPoS delegated-proof-of-stake consensus engine with the initial
@@ -417,11 +452,12 @@ func (c *XDPoS) verifyCascadingFields(chain consensus.ChainReader, header *types
if err == nil {
return c.verifySeal(chain, header, parents, fullVerify)
}
+
signers, err = c.GetSignersFromContract(chain, header)
if err != nil {
return err
}
-
+ err = c.checkSignersOnCheckpoint(chain, header, signers)
if err == nil {
return c.verifySeal(chain, header, parents, fullVerify)
}
@@ -431,7 +467,7 @@ func (c *XDPoS) verifyCascadingFields(chain consensus.ChainReader, header *types
func (c *XDPoS) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error {
number := header.Number.Uint64()
- // ignore signerCheck at checkpoint block 27307800 due to wrong snapshot at gap 27307799
+ // ignore signerCheck at checkpoint block 14458500 due to wrong snapshot at gap 14458495
if number == common.IgnoreSignerCheckBlock {
return nil
}
@@ -463,6 +499,7 @@ func (c *XDPoS) checkSignersOnCheckpoint(chain consensus.ChainReader, header *ty
extraSuffix := len(header.Extra) - extraSeal
masternodesFromCheckpointHeader := common.ExtractAddressFromBytes(header.Extra[extraVanity:extraSuffix])
validSigners := compareSignersLists(masternodesFromCheckpointHeader, signers)
+
if !validSigners {
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
return errInvalidCheckpointSigners
@@ -545,14 +582,14 @@ func whoIsCreator(snap *Snapshot, header *types.Header) (common.Address, error)
func (c *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
masternodes := c.GetMasternodes(chain, parent)
- if common.IsTestnet {
- // Only three mns hard code for XDC testnet.
- masternodes = []common.Address{
- common.HexToAddress("0xfFC679Dcdf444D2eEb0491A998E7902B411CcF20"),
- common.HexToAddress("0xd76fd76F7101811726DCE9E43C2617706a4c45c8"),
- common.HexToAddress("0x8A97753311aeAFACfd76a68Cf2e2a9808d3e65E8"),
- }
- }
+ // if common.IsTestnet {
+ // // Only three mns hard code for XDC testnet.
+ // masternodes = []common.Address{
+ // common.HexToAddress("0x3Ea0A3555f9B1dE983572BfF6444aeb1899eC58C"),
+ // common.HexToAddress("0x4F7900282F3d371d585ab1361205B0940aB1789C"),
+ // common.HexToAddress("0x942a5885A8844Ee5587C8AC5e371Fc39FFE61896"),
+ // }
+ // }
snap, err := c.GetSnapshot(chain, parent)
if err != nil {
@@ -921,7 +958,7 @@ func (c *XDPoS) UpdateMasternodes(chain consensus.ChainReader, header *types.Hea
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block.
-func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
+func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// set block reward
number := header.Number.Uint64()
rCheckpoint := chain.Config().XDPoS.RewardCheckpoint
@@ -929,7 +966,7 @@ func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, stat
// _ = c.CacheData(header, txs, receipts)
if c.HookReward != nil && number%rCheckpoint == 0 {
- err, rewards := c.HookReward(chain, state, header)
+ err, rewards := c.HookReward(chain, state, parentState, header)
if err != nil {
return nil, err
}
@@ -1061,7 +1098,7 @@ func (c *XDPoS) APIs(chain consensus.ChainReader) []rpc.API {
Namespace: "XDPoS",
Version: "1.0",
Service: &API{chain: chain, XDPoS: c},
- Public: false,
+ Public: true,
}}
}
@@ -1246,9 +1283,9 @@ func (c *XDPoS) CheckMNTurn(chain consensus.ChainReader, parent *types.Header, s
if common.IsTestnet {
// Only three mns hard code for XDC testnet.
masternodes = []common.Address{
- common.HexToAddress("0xfFC679Dcdf444D2eEb0491A998E7902B411CcF20"),
- common.HexToAddress("0xd76fd76F7101811726DCE9E43C2617706a4c45c8"),
- common.HexToAddress("0x8A97753311aeAFACfd76a68Cf2e2a9808d3e65E8"),
+ common.HexToAddress("0x3Ea0A3555f9B1dE983572BfF6444aeb1899eC58C"),
+ common.HexToAddress("0x4F7900282F3d371d585ab1361205B0940aB1789C"),
+ common.HexToAddress("0x942a5885A8844Ee5587C8AC5e371Fc39FFE61896"),
}
}
diff --git a/consensus/XDPoS/XDPoS_test.go b/consensus/XDPoS/XDPoS_test.go
index 7dec1f5435..e00d3eed03 100644
--- a/consensus/XDPoS/XDPoS_test.go
+++ b/consensus/XDPoS/XDPoS_test.go
@@ -5,9 +5,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func TestGetM1M2FromCheckpointHeader(t *testing.T) {
diff --git a/consensus/XDPoS/api.go b/consensus/XDPoS/api.go
index 72fa392d41..252ad07ff1 100644
--- a/consensus/XDPoS/api.go
+++ b/consensus/XDPoS/api.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -16,10 +16,11 @@
package XDPoS
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
+ "math/big"
)
// API is a user facing RPC API to allow controlling the signer and voting
@@ -28,6 +29,14 @@ type API struct {
chain consensus.ChainReader
XDPoS *XDPoS
}
+type NetworkInformation struct {
+ NetworkId *big.Int
+ XDCValidatorAddress common.Address
+ RelayerRegistrationAddress common.Address
+ XDCXListingAddress common.Address
+ XDCZAddress common.Address
+ LendingAddress common.Address
+}
// GetSnapshot retrieves the state snapshot at a given block.
func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
@@ -87,14 +96,22 @@ func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
return snap.GetSigners(), nil
}
-// Proposals returns the current proposals the node tries to uphold and vote on.
-func (api *API) Proposals() map[common.Address]bool {
+func (api *API) NetworkInformation() NetworkInformation {
api.XDPoS.lock.RLock()
defer api.XDPoS.lock.RUnlock()
-
- proposals := make(map[common.Address]bool)
- for address, auth := range api.XDPoS.proposals {
- proposals[address] = auth
+ info := NetworkInformation{}
+ info.NetworkId = api.chain.Config().ChainId
+ info.XDCValidatorAddress = common.HexToAddress(common.MasternodeVotingSMC)
+ if common.IsTestnet {
+ info.LendingAddress = common.HexToAddress(common.LendingRegistrationSMCTestnet)
+ info.RelayerRegistrationAddress = common.HexToAddress(common.RelayerRegistrationSMCTestnet)
+ info.XDCXListingAddress = common.XDCXListingSMCTestNet
+ info.XDCZAddress = common.TRC21IssuerSMCTestNet
+ } else {
+ info.LendingAddress = common.HexToAddress(common.LendingRegistrationSMC)
+ info.RelayerRegistrationAddress = common.HexToAddress(common.RelayerRegistrationSMC)
+ info.XDCXListingAddress = common.XDCXListingSMC
+ info.XDCZAddress = common.TRC21IssuerSMC
}
- return proposals
+ return info
}
diff --git a/consensus/XDPoS/snapshot.go b/consensus/XDPoS/snapshot.go
index 3449e63e86..8642f86b52 100644
--- a/consensus/XDPoS/snapshot.go
+++ b/consensus/XDPoS/snapshot.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -19,11 +19,11 @@ import (
"bytes"
"encoding/json"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus/clique"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/params"
lru "github.com/hashicorp/golang-lru"
)
diff --git a/consensus/clique/api.go b/consensus/clique/api.go
index b875eef012..a8c8aeb440 100644
--- a/consensus/clique/api.go
+++ b/consensus/clique/api.go
@@ -17,10 +17,10 @@
package clique
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
)
// API is a user facing RPC API to allow controlling the signer and voting
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index c2405ae297..7aa20c062a 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -25,20 +25,20 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/misc"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
lru "github.com/hashicorp/golang-lru"
)
@@ -569,7 +569,7 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block.
-func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
+func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go
index 9ebdb8df15..bc89168aff 100644
--- a/consensus/clique/snapshot.go
+++ b/consensus/clique/snapshot.go
@@ -20,10 +20,10 @@ import (
"bytes"
"encoding/json"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/params"
lru "github.com/hashicorp/golang-lru"
)
diff --git a/consensus/consensus.go b/consensus/consensus.go
index b02afa63c4..7ce64f0973 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -18,11 +18,11 @@
package consensus
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
"math/big"
)
@@ -82,7 +82,7 @@ type Engine interface {
// and assembles the final block.
// Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards).
- Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
+ Finalize(chain ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)
// Seal generates a new block for the given input block with the local miner's
@@ -104,3 +104,19 @@ type PoW interface {
// Hashrate returns the current mining hashrate of a PoW consensus engine.
Hashrate() float64
}
+
+// ChainContext supports retrieving headers and consensus parameters from the
+// current blockchain to be used during transaction processing.
+type ChainContext interface {
+ // Engine retrieves the chain's consensus engine.
+ Engine() Engine
+
+ // GetHeader returns the hash corresponding to their hash.
+ GetHeader(common.Hash, uint64) *types.Header
+
+ // CurrentHeader retrieves the current header from the local chain.
+ CurrentHeader() *types.Header
+
+ // Config retrieves the blockchain's chain configuration.
+ Config() *params.ChainConfig
+}
diff --git a/consensus/ethash/algorithm.go b/consensus/ethash/algorithm.go
index 905a7b1ea7..45e28f02bf 100644
--- a/consensus/ethash/algorithm.go
+++ b/consensus/ethash/algorithm.go
@@ -27,11 +27,11 @@ import (
"time"
"unsafe"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/bitutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
const (
diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go
index 841e39233f..699c47e544 100644
--- a/consensus/ethash/algorithm_test.go
+++ b/consensus/ethash/algorithm_test.go
@@ -25,9 +25,9 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// Tests whether the dataset size calculator works correctly by cross checking the
diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index 99eec82211..faa4c52302 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -24,14 +24,14 @@ import (
"runtime"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
- set "gopkg.in/fatih/set.v0"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/misc"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ mapset "github.com/deckarep/golang-set"
)
// Ethash proof-of-work protocol constants.
@@ -177,7 +177,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
return errTooManyUncles
}
// Gather the set of past uncles and ancestors
- uncles, ancestors := set.New(), make(map[common.Hash]*types.Header)
+ uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header)
number, parent := block.NumberU64()-1, block.ParentHash()
for i := 0; i < 7; i++ {
@@ -198,7 +198,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
for _, uncle := range block.Uncles() {
// Make sure every uncle is rewarded only once
hash := uncle.Hash()
- if uncles.Has(hash) {
+ if uncles.Contains(hash) {
return errDuplicateUncle
}
uncles.Add(hash)
@@ -513,7 +513,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header)
// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state and assembling the block.
-func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
+func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// Accumulate any block and uncle rewards and commit the final state root
accumulateRewards(chain.Config(), state, header, uncles)
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
diff --git a/consensus/ethash/consensus_test.go b/consensus/ethash/consensus_test.go
index 438a99dd66..3d56792cdd 100644
--- a/consensus/ethash/consensus_test.go
+++ b/consensus/ethash/consensus_test.go
@@ -23,9 +23,9 @@ import (
"path/filepath"
"testing"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
type diffTest struct {
diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go
index 1b3dcee302..a65468f571 100644
--- a/consensus/ethash/ethash.go
+++ b/consensus/ethash/ethash.go
@@ -32,11 +32,11 @@ import (
"time"
"unsafe"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/metrics"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
mmap "github.com/edsrzf/mmap-go"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/hashicorp/golang-lru/simplelru"
)
diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go
index 31116da437..d4f205df00 100644
--- a/consensus/ethash/ethash_test.go
+++ b/consensus/ethash/ethash_test.go
@@ -24,7 +24,7 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// Tests that ethash works correctly in test mode.
@@ -44,7 +44,7 @@ func TestTestMode(t *testing.T) {
}
// This test checks that cache lru logic doesn't crash under load.
-// It reproduces https://github.com/ethereum/go-ethereum/issues/14943
+// It reproduces https://github.com/XinFinOrg/XDPoSChain/issues/14943
func TestCacheFileEvict(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "ethash-test")
if err != nil {
diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go
index b5e742d8bb..754052fe95 100644
--- a/consensus/ethash/sealer.go
+++ b/consensus/ethash/sealer.go
@@ -24,10 +24,10 @@ import (
"runtime"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// Seal implements consensus.Engine, attempting to find a nonce that satisfies
diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go
index 9b22bd7a52..e8af25a69a 100644
--- a/consensus/misc/dao.go
+++ b/consensus/misc/dao.go
@@ -21,9 +21,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
var (
diff --git a/consensus/misc/forks.go b/consensus/misc/forks.go
index 4a5e7c37e0..910ed620c5 100644
--- a/consensus/misc/forks.go
+++ b/consensus/misc/forks.go
@@ -19,9 +19,9 @@ package misc
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// VerifyForkHashes verifies that blocks conforming to network hard-forks do have
diff --git a/console/bridge.go b/console/bridge.go
index b28cc438e2..940c353431 100644
--- a/console/bridge.go
+++ b/console/bridge.go
@@ -23,9 +23,9 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts/usbwallet"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
"github.com/robertkrimen/otto"
)
diff --git a/console/console.go b/console/console.go
index d843044ffc..12ec9ec9bf 100644
--- a/console/console.go
+++ b/console/console.go
@@ -28,9 +28,9 @@ import (
"strings"
"syscall"
- "github.com/ethereum/go-ethereum/internal/jsre"
- "github.com/ethereum/go-ethereum/internal/web3ext"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/XinFinOrg/XDPoSChain/internal/jsre"
+ "github.com/XinFinOrg/XDPoSChain/internal/web3ext"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
"github.com/mattn/go-colorable"
"github.com/peterh/liner"
"github.com/robertkrimen/otto"
diff --git a/console/console_test.go b/console/console_test.go
index 8b21d4531a..42d7b0254b 100644
--- a/console/console_test.go
+++ b/console/console_test.go
@@ -19,18 +19,20 @@ package console
import (
"bytes"
"errors"
+ "github.com/XinFinOrg/XDPoSChain/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending"
"io/ioutil"
"os"
"strings"
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/internal/jsre"
- "github.com/ethereum/go-ethereum/node"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/eth"
+ "github.com/XinFinOrg/XDPoSChain/internal/jsre"
+ "github.com/XinFinOrg/XDPoSChain/node"
)
const (
@@ -104,7 +106,9 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester {
if confOverride != nil {
confOverride(ethConf)
}
- if err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil {
+ if err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ return eth.New(ctx, ethConf, &XDCx.XDCX{}, &XDCxlending.Lending{})
+ }); err != nil {
t.Fatalf("failed to register Ethereum protocol: %v", err)
}
// Start the node and assemble the JavaScript console around it
diff --git a/contracts/XDCx/XDCxListing.go b/contracts/XDCx/XDCxListing.go
new file mode 100644
index 0000000000..1e44f7127f
--- /dev/null
+++ b/contracts/XDCx/XDCxListing.go
@@ -0,0 +1,40 @@
+package XDCx
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+)
+
+type XDCXListing struct {
+ *contract.XDCXListingSession
+ contractBackend bind.ContractBackend
+}
+
+func NewMyXDCXListing(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*XDCXListing, error) {
+ smartContract, err := contract.NewXDCXListing(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &XDCXListing{
+ &contract.XDCXListingSession{
+ Contract: smartContract,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployXDCXListing(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *XDCXListing, error) {
+ contractAddr, _, _, err := contract.DeployXDCXListing(transactOpts, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ smartContract, err := NewMyXDCXListing(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, smartContract, nil
+}
diff --git a/contracts/XDCx/contract/LendingRegistration.go b/contracts/XDCx/contract/LendingRegistration.go
new file mode 100644
index 0000000000..85001120a1
--- /dev/null
+++ b/contracts/XDCx/contract/LendingRegistration.go
@@ -0,0 +1,1301 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+)
+
+// LAbstractRegistrationABI is the input ABI used to generate the binding from.
+const LAbstractRegistrationABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"RESIGN_REQUESTS\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"getRelayerByCoinbase\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint16\"},{\"name\":\"\",\"type\":\"address[]\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
+
+// LAbstractRegistrationBin is the compiled bytecode used for deploying new contracts.
+const LAbstractRegistrationBin = `0x`
+
+// DeployLAbstractRegistration deploys a new Ethereum contract, binding an instance of LAbstractRegistration to it.
+func DeployLAbstractRegistration(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LAbstractRegistration, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractRegistrationABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(LAbstractRegistrationBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &LAbstractRegistration{LAbstractRegistrationCaller: LAbstractRegistrationCaller{contract: contract}, LAbstractRegistrationTransactor: LAbstractRegistrationTransactor{contract: contract}, LAbstractRegistrationFilterer: LAbstractRegistrationFilterer{contract: contract}}, nil
+}
+
+// LAbstractRegistration is an auto generated Go binding around an Ethereum contract.
+type LAbstractRegistration struct {
+ LAbstractRegistrationCaller // Read-only binding to the contract
+ LAbstractRegistrationTransactor // Write-only binding to the contract
+ LAbstractRegistrationFilterer // Log filterer for contract events
+}
+
+// LAbstractRegistrationCaller is an auto generated read-only Go binding around an Ethereum contract.
+type LAbstractRegistrationCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractRegistrationTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type LAbstractRegistrationTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractRegistrationFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type LAbstractRegistrationFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractRegistrationSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type LAbstractRegistrationSession struct {
+ Contract *LAbstractRegistration // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractRegistrationCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type LAbstractRegistrationCallerSession struct {
+ Contract *LAbstractRegistrationCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// LAbstractRegistrationTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type LAbstractRegistrationTransactorSession struct {
+ Contract *LAbstractRegistrationTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractRegistrationRaw is an auto generated low-level Go binding around an Ethereum contract.
+type LAbstractRegistrationRaw struct {
+ Contract *LAbstractRegistration // Generic contract binding to access the raw methods on
+}
+
+// LAbstractRegistrationCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type LAbstractRegistrationCallerRaw struct {
+ Contract *LAbstractRegistrationCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// LAbstractRegistrationTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type LAbstractRegistrationTransactorRaw struct {
+ Contract *LAbstractRegistrationTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewLAbstractRegistration creates a new instance of LAbstractRegistration, bound to a specific deployed contract.
+func NewLAbstractRegistration(address common.Address, backend bind.ContractBackend) (*LAbstractRegistration, error) {
+ contract, err := bindLAbstractRegistration(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractRegistration{LAbstractRegistrationCaller: LAbstractRegistrationCaller{contract: contract}, LAbstractRegistrationTransactor: LAbstractRegistrationTransactor{contract: contract}, LAbstractRegistrationFilterer: LAbstractRegistrationFilterer{contract: contract}}, nil
+}
+
+// NewLAbstractRegistrationCaller creates a new read-only instance of LAbstractRegistration, bound to a specific deployed contract.
+func NewLAbstractRegistrationCaller(address common.Address, caller bind.ContractCaller) (*LAbstractRegistrationCaller, error) {
+ contract, err := bindLAbstractRegistration(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractRegistrationCaller{contract: contract}, nil
+}
+
+// NewLAbstractRegistrationTransactor creates a new write-only instance of LAbstractRegistration, bound to a specific deployed contract.
+func NewLAbstractRegistrationTransactor(address common.Address, transactor bind.ContractTransactor) (*LAbstractRegistrationTransactor, error) {
+ contract, err := bindLAbstractRegistration(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractRegistrationTransactor{contract: contract}, nil
+}
+
+// NewLAbstractRegistrationFilterer creates a new log filterer instance of LAbstractRegistration, bound to a specific deployed contract.
+func NewLAbstractRegistrationFilterer(address common.Address, filterer bind.ContractFilterer) (*LAbstractRegistrationFilterer, error) {
+ contract, err := bindLAbstractRegistration(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractRegistrationFilterer{contract: contract}, nil
+}
+
+// bindLAbstractRegistration binds a generic wrapper to an already deployed contract.
+func bindLAbstractRegistration(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractRegistrationABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractRegistration *LAbstractRegistrationRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractRegistration.Contract.LAbstractRegistrationCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractRegistration *LAbstractRegistrationRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractRegistration.Contract.LAbstractRegistrationTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractRegistration *LAbstractRegistrationRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractRegistration.Contract.LAbstractRegistrationTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractRegistration *LAbstractRegistrationCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractRegistration.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractRegistration *LAbstractRegistrationTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractRegistration.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractRegistration *LAbstractRegistrationTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractRegistration.Contract.contract.Transact(opts, method, params...)
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_LAbstractRegistration *LAbstractRegistrationCaller) RESIGNREQUESTS(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _LAbstractRegistration.contract.Call(opts, out, "RESIGN_REQUESTS", arg0)
+ return *ret0, err
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_LAbstractRegistration *LAbstractRegistrationSession) RESIGNREQUESTS(arg0 common.Address) (*big.Int, error) {
+ return _LAbstractRegistration.Contract.RESIGNREQUESTS(&_LAbstractRegistration.CallOpts, arg0)
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_LAbstractRegistration *LAbstractRegistrationCallerSession) RESIGNREQUESTS(arg0 common.Address) (*big.Int, error) {
+ return _LAbstractRegistration.Contract.RESIGNREQUESTS(&_LAbstractRegistration.CallOpts, arg0)
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase( address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_LAbstractRegistration *LAbstractRegistrationCaller) GetRelayerByCoinbase(opts *bind.CallOpts, arg0 common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ var (
+ ret0 = new(*big.Int)
+ ret1 = new(common.Address)
+ ret2 = new(*big.Int)
+ ret3 = new(uint16)
+ ret4 = new([]common.Address)
+ ret5 = new([]common.Address)
+ )
+ out := &[]interface{}{
+ ret0,
+ ret1,
+ ret2,
+ ret3,
+ ret4,
+ ret5,
+ }
+ err := _LAbstractRegistration.contract.Call(opts, out, "getRelayerByCoinbase", arg0)
+ return *ret0, *ret1, *ret2, *ret3, *ret4, *ret5, err
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase( address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_LAbstractRegistration *LAbstractRegistrationSession) GetRelayerByCoinbase(arg0 common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ return _LAbstractRegistration.Contract.GetRelayerByCoinbase(&_LAbstractRegistration.CallOpts, arg0)
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase( address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_LAbstractRegistration *LAbstractRegistrationCallerSession) GetRelayerByCoinbase(arg0 common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ return _LAbstractRegistration.Contract.GetRelayerByCoinbase(&_LAbstractRegistration.CallOpts, arg0)
+}
+
+// LAbstractXDCXListingABI is the input ABI used to generate the binding from.
+const LAbstractXDCXListingABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"getTokenStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
+
+// LAbstractXDCXListingBin is the compiled bytecode used for deploying new contracts.
+const LAbstractXDCXListingBin = `0x`
+
+// DeployLAbstractXDCXListing deploys a new Ethereum contract, binding an instance of LAbstractXDCXListing to it.
+func DeployLAbstractXDCXListing(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LAbstractXDCXListing, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractXDCXListingABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(LAbstractXDCXListingBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &LAbstractXDCXListing{LAbstractXDCXListingCaller: LAbstractXDCXListingCaller{contract: contract}, LAbstractXDCXListingTransactor: LAbstractXDCXListingTransactor{contract: contract}, LAbstractXDCXListingFilterer: LAbstractXDCXListingFilterer{contract: contract}}, nil
+}
+
+// LAbstractXDCXListing is an auto generated Go binding around an Ethereum contract.
+type LAbstractXDCXListing struct {
+ LAbstractXDCXListingCaller // Read-only binding to the contract
+ LAbstractXDCXListingTransactor // Write-only binding to the contract
+ LAbstractXDCXListingFilterer // Log filterer for contract events
+}
+
+// LAbstractXDCXListingCaller is an auto generated read-only Go binding around an Ethereum contract.
+type LAbstractXDCXListingCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractXDCXListingTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type LAbstractXDCXListingTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractXDCXListingFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type LAbstractXDCXListingFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractXDCXListingSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type LAbstractXDCXListingSession struct {
+ Contract *LAbstractXDCXListing // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractXDCXListingCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type LAbstractXDCXListingCallerSession struct {
+ Contract *LAbstractXDCXListingCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// LAbstractXDCXListingTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type LAbstractXDCXListingTransactorSession struct {
+ Contract *LAbstractXDCXListingTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractXDCXListingRaw is an auto generated low-level Go binding around an Ethereum contract.
+type LAbstractXDCXListingRaw struct {
+ Contract *LAbstractXDCXListing // Generic contract binding to access the raw methods on
+}
+
+// LAbstractXDCXListingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type LAbstractXDCXListingCallerRaw struct {
+ Contract *LAbstractXDCXListingCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// LAbstractXDCXListingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type LAbstractXDCXListingTransactorRaw struct {
+ Contract *LAbstractXDCXListingTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewLAbstractXDCXListing creates a new instance of LAbstractXDCXListing, bound to a specific deployed contract.
+func NewLAbstractXDCXListing(address common.Address, backend bind.ContractBackend) (*LAbstractXDCXListing, error) {
+ contract, err := bindLAbstractXDCXListing(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractXDCXListing{LAbstractXDCXListingCaller: LAbstractXDCXListingCaller{contract: contract}, LAbstractXDCXListingTransactor: LAbstractXDCXListingTransactor{contract: contract}, LAbstractXDCXListingFilterer: LAbstractXDCXListingFilterer{contract: contract}}, nil
+}
+
+// NewLAbstractXDCXListingCaller creates a new read-only instance of LAbstractXDCXListing, bound to a specific deployed contract.
+func NewLAbstractXDCXListingCaller(address common.Address, caller bind.ContractCaller) (*LAbstractXDCXListingCaller, error) {
+ contract, err := bindLAbstractXDCXListing(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractXDCXListingCaller{contract: contract}, nil
+}
+
+// NewLAbstractXDCXListingTransactor creates a new write-only instance of LAbstractXDCXListing, bound to a specific deployed contract.
+func NewLAbstractXDCXListingTransactor(address common.Address, transactor bind.ContractTransactor) (*LAbstractXDCXListingTransactor, error) {
+ contract, err := bindLAbstractXDCXListing(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractXDCXListingTransactor{contract: contract}, nil
+}
+
+// NewLAbstractXDCXListingFilterer creates a new log filterer instance of LAbstractXDCXListing, bound to a specific deployed contract.
+func NewLAbstractXDCXListingFilterer(address common.Address, filterer bind.ContractFilterer) (*LAbstractXDCXListingFilterer, error) {
+ contract, err := bindLAbstractXDCXListing(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractXDCXListingFilterer{contract: contract}, nil
+}
+
+// bindLAbstractXDCXListing binds a generic wrapper to an already deployed contract.
+func bindLAbstractXDCXListing(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractXDCXListingABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractXDCXListing.Contract.LAbstractXDCXListingCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractXDCXListing.Contract.LAbstractXDCXListingTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractXDCXListing.Contract.LAbstractXDCXListingTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractXDCXListing *LAbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractXDCXListing.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractXDCXListing *LAbstractXDCXListingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractXDCXListing.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractXDCXListing *LAbstractXDCXListingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractXDCXListing.Contract.contract.Transact(opts, method, params...)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_LAbstractXDCXListing *LAbstractXDCXListingCaller) GetTokenStatus(opts *bind.CallOpts, arg0 common.Address) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _LAbstractXDCXListing.contract.Call(opts, out, "getTokenStatus", arg0)
+ return *ret0, err
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_LAbstractXDCXListing *LAbstractXDCXListingSession) GetTokenStatus(arg0 common.Address) (bool, error) {
+ return _LAbstractXDCXListing.Contract.GetTokenStatus(&_LAbstractXDCXListing.CallOpts, arg0)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_LAbstractXDCXListing *LAbstractXDCXListingCallerSession) GetTokenStatus(arg0 common.Address) (bool, error) {
+ return _LAbstractXDCXListing.Contract.GetTokenStatus(&_LAbstractXDCXListing.CallOpts, arg0)
+}
+
+// LAbstractTokenTRC21ABI is the input ABI used to generate the binding from.
+const LAbstractTokenTRC21ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"issuer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
+
+// LAbstractTokenTRC21Bin is the compiled bytecode used for deploying new contracts.
+const LAbstractTokenTRC21Bin = `0x`
+
+// DeployLAbstractTokenTRC21 deploys a new Ethereum contract, binding an instance of LAbstractTokenTRC21 to it.
+func DeployLAbstractTokenTRC21(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LAbstractTokenTRC21, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractTokenTRC21ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(LAbstractTokenTRC21Bin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &LAbstractTokenTRC21{LAbstractTokenTRC21Caller: LAbstractTokenTRC21Caller{contract: contract}, LAbstractTokenTRC21Transactor: LAbstractTokenTRC21Transactor{contract: contract}, LAbstractTokenTRC21Filterer: LAbstractTokenTRC21Filterer{contract: contract}}, nil
+}
+
+// LAbstractTokenTRC21 is an auto generated Go binding around an Ethereum contract.
+type LAbstractTokenTRC21 struct {
+ LAbstractTokenTRC21Caller // Read-only binding to the contract
+ LAbstractTokenTRC21Transactor // Write-only binding to the contract
+ LAbstractTokenTRC21Filterer // Log filterer for contract events
+}
+
+// LAbstractTokenTRC21Caller is an auto generated read-only Go binding around an Ethereum contract.
+type LAbstractTokenTRC21Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractTokenTRC21Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type LAbstractTokenTRC21Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractTokenTRC21Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type LAbstractTokenTRC21Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LAbstractTokenTRC21Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type LAbstractTokenTRC21Session struct {
+ Contract *LAbstractTokenTRC21 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractTokenTRC21CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type LAbstractTokenTRC21CallerSession struct {
+ Contract *LAbstractTokenTRC21Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// LAbstractTokenTRC21TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type LAbstractTokenTRC21TransactorSession struct {
+ Contract *LAbstractTokenTRC21Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LAbstractTokenTRC21Raw is an auto generated low-level Go binding around an Ethereum contract.
+type LAbstractTokenTRC21Raw struct {
+ Contract *LAbstractTokenTRC21 // Generic contract binding to access the raw methods on
+}
+
+// LAbstractTokenTRC21CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type LAbstractTokenTRC21CallerRaw struct {
+ Contract *LAbstractTokenTRC21Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// LAbstractTokenTRC21TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type LAbstractTokenTRC21TransactorRaw struct {
+ Contract *LAbstractTokenTRC21Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewLAbstractTokenTRC21 creates a new instance of LAbstractTokenTRC21, bound to a specific deployed contract.
+func NewLAbstractTokenTRC21(address common.Address, backend bind.ContractBackend) (*LAbstractTokenTRC21, error) {
+ contract, err := bindLAbstractTokenTRC21(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractTokenTRC21{LAbstractTokenTRC21Caller: LAbstractTokenTRC21Caller{contract: contract}, LAbstractTokenTRC21Transactor: LAbstractTokenTRC21Transactor{contract: contract}, LAbstractTokenTRC21Filterer: LAbstractTokenTRC21Filterer{contract: contract}}, nil
+}
+
+// NewLAbstractTokenTRC21Caller creates a new read-only instance of LAbstractTokenTRC21, bound to a specific deployed contract.
+func NewLAbstractTokenTRC21Caller(address common.Address, caller bind.ContractCaller) (*LAbstractTokenTRC21Caller, error) {
+ contract, err := bindLAbstractTokenTRC21(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractTokenTRC21Caller{contract: contract}, nil
+}
+
+// NewLAbstractTokenTRC21Transactor creates a new write-only instance of LAbstractTokenTRC21, bound to a specific deployed contract.
+func NewLAbstractTokenTRC21Transactor(address common.Address, transactor bind.ContractTransactor) (*LAbstractTokenTRC21Transactor, error) {
+ contract, err := bindLAbstractTokenTRC21(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractTokenTRC21Transactor{contract: contract}, nil
+}
+
+// NewLAbstractTokenTRC21Filterer creates a new log filterer instance of LAbstractTokenTRC21, bound to a specific deployed contract.
+func NewLAbstractTokenTRC21Filterer(address common.Address, filterer bind.ContractFilterer) (*LAbstractTokenTRC21Filterer, error) {
+ contract, err := bindLAbstractTokenTRC21(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &LAbstractTokenTRC21Filterer{contract: contract}, nil
+}
+
+// bindLAbstractTokenTRC21 binds a generic wrapper to an already deployed contract.
+func bindLAbstractTokenTRC21(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(LAbstractTokenTRC21ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractTokenTRC21.Contract.LAbstractTokenTRC21Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractTokenTRC21.Contract.LAbstractTokenTRC21Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractTokenTRC21.Contract.LAbstractTokenTRC21Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _LAbstractTokenTRC21.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LAbstractTokenTRC21.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LAbstractTokenTRC21.Contract.contract.Transact(opts, method, params...)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _LAbstractTokenTRC21.contract.Call(opts, out, "issuer")
+ return *ret0, err
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Session) Issuer() (common.Address, error) {
+ return _LAbstractTokenTRC21.Contract.Issuer(&_LAbstractTokenTRC21.CallOpts)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_LAbstractTokenTRC21 *LAbstractTokenTRC21CallerSession) Issuer() (common.Address, error) {
+ return _LAbstractTokenTRC21.Contract.Issuer(&_LAbstractTokenTRC21.CallOpts)
+}
+
+// LendingABI is the input ABI used to generate the binding from.
+const LendingABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"COLLATERALS\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ORACLE_PRICE_FEEDER\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"term\",\"type\":\"uint256\"}],\"name\":\"addTerm\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"LENDINGRELAYER_LIST\",\"outputs\":[{\"name\":\"_tradeFee\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"Relayer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"XDCXListing\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"name\":\"baseTokens\",\"type\":\"address[]\"},{\"name\":\"terms\",\"type\":\"uint256[]\"},{\"name\":\"collaterals\",\"type\":\"address[]\"}],\"name\":\"update\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MODERATOR\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"depositRate\",\"type\":\"uint256\"},{\"name\":\"liquidationRate\",\"type\":\"uint256\"},{\"name\":\"recallRate\",\"type\":\"uint256\"}],\"name\":\"addILOCollateral\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"tradeFee\",\"type\":\"uint16\"}],\"name\":\"updateFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"moderator\",\"type\":\"address\"}],\"name\":\"changeModerator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"TERMS\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"BASES\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"COLLATERAL_LIST\",\"outputs\":[{\"name\":\"_depositRate\",\"type\":\"uint256\"},{\"name\":\"_liquidationRate\",\"type\":\"uint256\"},{\"name\":\"_recallRate\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"addBaseToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"lendingToken\",\"type\":\"address\"},{\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"setCollateralPrice\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"ILO_COLLATERALS\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"feeder\",\"type\":\"address\"}],\"name\":\"changeOraclePriceFeeder\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"depositRate\",\"type\":\"uint256\"},{\"name\":\"liquidationRate\",\"type\":\"uint256\"},{\"name\":\"recallRate\",\"type\":\"uint256\"}],\"name\":\"addCollateral\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"lendingToken\",\"type\":\"address\"}],\"name\":\"getCollateralPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"getLendingRelayerByCoinbase\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"},{\"name\":\"\",\"type\":\"address[]\"},{\"name\":\"\",\"type\":\"uint256[]\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"r\",\"type\":\"address\"},{\"name\":\"t\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"
+
+// LendingBin is the compiled bytecode used for deploying new contracts.
+const LendingBin = `0x608060405234801561001057600080fd5b506040516040806124e183398101604052805160209091015160068054600160a060020a0319908116600160a060020a03948516179091556008805482169390921692909217905560098054339083168117909155600780549092161790556124638061007e6000396000f3006080604052600436106101035763ffffffff60e060020a6000350416630811f05a81146101085780630c4c2cbb1461013c5780630c655955146101515780630faf292c1461016b578063264949d8146101a357806329a4ddec146101b85780632ddada4c146101cd57806334b4e625146102aa5780633b874827146102bf5780633ea2391f146102e9578063466429211461031157806356327f57146103325780636d1dc42a1461035c578063822507011461037457806383e280d9146103b3578063acb8cd92146103d4578063b8687ec4146103fe578063c38f473f14610416578063e5eecf6814610437578063f2dbd07014610461578063fe824700146104a1575b600080fd5b34801561011457600080fd5b506101206004356105af565b60408051600160a060020a039092168252519081900360200190f35b34801561014857600080fd5b506101206105d7565b34801561015d57600080fd5b506101696004356105e6565b005b34801561017757600080fd5b5061018c600160a060020a0360043516610728565b6040805161ffff9092168252519081900360200190f35b3480156101af57600080fd5b5061012061073e565b3480156101c457600080fd5b5061012061074d565b3480156101d957600080fd5b506040805160206004604435818101358381028086018501909652808552610169958335600160a060020a0316956024803561ffff1696369695606495939492019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061075c9650505050505050565b3480156102b657600080fd5b50610120610e9b565b3480156102cb57600080fd5b50610169600160a060020a0360043516602435604435606435610eaa565b3480156102f557600080fd5b50610169600160a060020a036004351661ffff60243516611313565b34801561031d57600080fd5b50610169600160a060020a0360043516611664565b34801561033e57600080fd5b5061034a6004356116eb565b60408051918252519081900360200190f35b34801561036857600080fd5b5061012060043561170a565b34801561038057600080fd5b50610395600160a060020a0360043516611718565b60408051938452602084019290925282820152519081900360600190f35b3480156103bf57600080fd5b50610169600160a060020a0360043516611738565b3480156103e057600080fd5b50610169600160a060020a0360043581169060243516604435611930565b34801561040a57600080fd5b50610120600435611d11565b34801561042257600080fd5b50610169600160a060020a0360043516611d1f565b34801561044357600080fd5b50610169600160a060020a0360043516602435604435606435611db8565b34801561046d57600080fd5b50610488600160a060020a03600435811690602435166120f2565b6040805192835260208301919091528051918290030190f35b3480156104ad57600080fd5b506104c2600160a060020a0360043516612129565b604051808561ffff1661ffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015610518578181015183820152602001610500565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561055757818101518382015260200161053f565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561059657818101518382015260200161057e565b5050505090500197505050505050505060405180910390f35b60028054829081106105bd57fe5b600091825260209091200154600160a060020a0316905081565b600954600160a060020a031681565b600754600160a060020a03163314610636576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206123f8833981519152604482015290519081900360640190fd5b603c81101561068f576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964207465726d0000000000000000000000000000000000000000604482015290519081900360640190fd5b6106e960048054806020026020016040519081016040528092919081815260200182805480156106de57602002820191906000526020600020905b8154815260200190600101908083116106ca575b505050505082612272565b151561072557600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b018190555b50565b60006020819052908152604090205461ffff1681565b600654600160a060020a031681565b600854600160a060020a031681565b600654604080517f540105c7000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015291516000938493849391169163540105c791602480820192869290919082900301818387803b1580156107c857600080fd5b505af11580156107dc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561080557600080fd5b81516020830151604084015160608501516080860180519496939592949193928301929164010000000081111561083b57600080fd5b8201602081018481111561084e57600080fd5b815185602082028301116401000000008211171561086b57600080fd5b5050929190602001805164010000000081111561088757600080fd5b8201602081018481111561089a57600080fd5b81518560208202830111640100000000821117156108b757600080fd5b50979b505050600160a060020a038a163314965061092695505050505050576040805160e560020a62461bcd02815260206004820152601660248201527f52656c61796572206f776e657220726571756972656400000000000000000000604482015290519081900360640190fd5b600654604080517f500f99f7000000000000000000000000000000000000000000000000000000008152600160a060020a038b811660048301529151919092169163500f99f79160248083019260209291908290030181600087803b15801561098e57600080fd5b505af11580156109a2573d6000803e3d6000fd5b505050506040513d60208110156109b857600080fd5b505115610a0f576040805160e560020a62461bcd02815260206004820152601960248201527f52656c6179657220726571756972656420746f20636c6f736500000000000000604482015290519081900360640190fd5b60008761ffff1610158015610a2957506103e88761ffff16105b1515610a7f576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420747261646520466565000000000000000000000000000000604482015290519081900360640190fd5b8451865114610ad8576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f742076616c6964206e756d626572206f66207465726d7300000000000000604482015290519081900360640190fd5b8351865114610b31576040805160e560020a62461bcd02815260206004820152601f60248201527f4e6f742076616c6964206e756d626572206f6620636f6c6c61746572616c7300604482015290519081900360640190fd5b5060009050805b8551811015610c2057610bbc6003805480602002602001604051908101604052809291908181526020018280548015610b9a57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b7c575b50505050508783815181101515610bad57fe5b906020019060200201516122bb565b9150600182151514610c18576040805160e560020a62461bcd02815260206004820152601560248201527f496e76616c6964206c656e64696e6720746f6b656e0000000000000000000000604482015290519081900360640190fd5b600101610b38565b5060005b8451811015610d0257610c9e6004805480602002602001604051908101604052809291908181526020018280548015610c7c57602002820191906000526020600020905b815481526020019060010190808311610c68575b50505050508683815181101515610c8f57fe5b90602001906020020151612272565b9150600182151514610cfa576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964207465726d0000000000000000000000000000000000000000604482015290519081900360640190fd5b600101610c24565b5060005b8351811015610df0578351600090859083908110610d2057fe5b60209081029091010151600160a060020a031614610de857610da46005805480602002602001604051908101604052809291908181526020018280548015610d9157602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610d73575b50505050508583815181101515610bad57fe5b1515610de8576040805160e560020a62461bcd0281526020600482015260126024820152600080516020612418833981519152604482015290519081900360640190fd5b600101610d06565b6040805160808101825261ffff898116825260208083018a81528385018a905260608401899052600160a060020a038d166000908152808352949094208351815461ffff191693169290921782559251805192939192610e56926001850192019061230a565b5060408201518051610e7291600284019160209091019061236f565b5060608201518051610e8e91600384019160209091019061230a565b5050505050505050505050565b600754600160a060020a031681565b60008060648510158015610ebe5750606484115b1515610f14576040805160e560020a62461bcd02815260206004820152600d60248201527f496e76616c696420726174657300000000000000000000000000000000000000604482015290519081900360640190fd5b838511610f6b576040805160e560020a62461bcd02815260206004820152601560248201527f496e76616c6964206465706f7369742072617465730000000000000000000000604482015290519081900360640190fd5b848311610fc2576040805160e560020a62461bcd02815260206004820152601460248201527f496e76616c696420726563616c6c207261746573000000000000000000000000604482015290519081900360640190fd5b611026600280548060200260200160405190810160405280929190818152602001828054801561101b57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610ffd575b5050505050876122bb565b1561107b576040805160e560020a62461bcd02815260206004820152601660248201527f496e76616c696420494c4f20636f6c6c61746572616c00000000000000000000604482015290519081900360640190fd5b6008546040805160e060020a63a3ff31b5028152600160a060020a0389811660048301529151919092169163a3ff31b59160248083019260209291908290030181600087803b1580156110cd57600080fd5b505af11580156110e1573d6000803e3d6000fd5b505050506040513d60208110156110f757600080fd5b50519150811515611140576040805160e560020a62461bcd0281526020600482015260126024820152600080516020612418833981519152604482015290519081900360640190fd5b85905033600160a060020a031681600160a060020a0316631d1438486040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561118b57600080fd5b505af115801561119f573d6000803e3d6000fd5b505050506040513d60208110156111b557600080fd5b5051600160a060020a031614611215576040805160e560020a62461bcd02815260206004820152601560248201527f526571756972656420746f6b656e206973737565720000000000000000000000604482015290519081900360640190fd5b604080516060810182528681526020808201878152828401878152600160a060020a038b1660009081526001808552908690209451855591519184019190915551600290920191909155600580548351818402810184019094528084526112b9939283018282801561101b57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610ffd575050505050876122bb565b151561130b57600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0018054600160a060020a031916600160a060020a0388161790555b505050505050565b600654604080517f540105c7000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151600093929092169163540105c791602480820192869290919082900301818387803b15801561137d57600080fd5b505af1158015611391573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c08110156113ba57600080fd5b8151602083015160408401516060850151608086018051949693959294919392830192916401000000008111156113f057600080fd5b8201602081018481111561140357600080fd5b815185602082028301116401000000008211171561142057600080fd5b5050929190602001805164010000000081111561143c57600080fd5b8201602081018481111561144f57600080fd5b815185602082028301116401000000008211171561146c57600080fd5b509799505050600160a060020a038816331496506114db95505050505050576040805160e560020a62461bcd02815260206004820152601660248201527f52656c61796572206f776e657220726571756972656400000000000000000000604482015290519081900360640190fd5b600654604080517f500f99f7000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301529151919092169163500f99f79160248083019260209291908290030181600087803b15801561154357600080fd5b505af1158015611557573d6000803e3d6000fd5b505050506040513d602081101561156d57600080fd5b5051156115c4576040805160e560020a62461bcd02815260206004820152601960248201527f52656c6179657220726571756972656420746f20636c6f736500000000000000604482015290519081900360640190fd5b60008261ffff16101580156115de57506103e88261ffff16105b1515611634576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420747261646520466565000000000000000000000000000000604482015290519081900360640190fd5b50600160a060020a03919091166000908152602081905260409020805461ffff191661ffff909216919091179055565b600754600160a060020a031633146116b4576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206123f8833981519152604482015290519081900360640190fd5b600160a060020a03811615156116c957600080fd5b60078054600160a060020a031916600160a060020a0392909216919091179055565b60048054829081106116f957fe5b600091825260209091200154905081565b60038054829081106105bd57fe5b600160208190526000918252604090912080549181015460029091015483565b600754600090600160a060020a0316331461178b576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206123f8833981519152604482015290519081900360640190fd5b6008546040805160e060020a63a3ff31b5028152600160a060020a0385811660048301529151919092169163a3ff31b59160248083019260209291908290030181600087803b1580156117dd57600080fd5b505af11580156117f1573d6000803e3d6000fd5b505050506040513d602081101561180757600080fd5b50518061181d5750600160a060020a0382166001145b9050801515611876576040805160e560020a62461bcd02815260206004820152601260248201527f496e76616c6964206261736520746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b6118da60038054806020026020016040519081016040528092919081815260200182805480156118cf57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116118b1575b5050505050836122bb565b151561192c57600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b018054600160a060020a031916600160a060020a0384161790555b5050565b6008546040805160e060020a63a3ff31b5028152600160a060020a03868116600483015291516000938493169163a3ff31b591602480830192602092919082900301818787803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b505050506040513d60208110156119ad57600080fd5b5051806119c35750600160a060020a0385166001145b9150811515611a0a576040805160e560020a62461bcd0281526020600482015260126024820152600080516020612418833981519152604482015290519081900360640190fd5b611a6e6003805480602002602001604051908101604052809291908181526020018280548015611a6357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611a45575b5050505050856122bb565b1515611ac4576040805160e560020a62461bcd02815260206004820152601560248201527f496e76616c6964206c656e64696e6720746f6b656e0000000000000000000000604482015290519081900360640190fd5b600160a060020a03851660009081526001602052604090205460641115611b23576040805160e560020a62461bcd0281526020600482015260126024820152600080516020612418833981519152604482015290519081900360640190fd5b611b876002805480602002602001604051908101604052809291908181526020018280548015611b7c57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611b5e575b5050505050866122bb565b15611bf357600954600160a060020a03163314611bee576040805160e560020a62461bcd02815260206004820152601c60248201527f4f7261636c652050726963652046656564657220726571756972656400000000604482015290519081900360640190fd5b611cc8565b84905033600160a060020a031681600160a060020a0316631d1438486040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b505050506040513d6020811015611c6857600080fd5b5051600160a060020a031614611cc8576040805160e560020a62461bcd02815260206004820152601560248201527f526571756972656420746f6b656e206973737565720000000000000000000000604482015290519081900360640190fd5b5050604080518082018252918252436020808401918252600160a060020a0395861660009081526001808352848220969097168152600390950190529220905181559051910155565b60058054829081106105bd57fe5b600954600160a060020a03163314611d81576040805160e560020a62461bcd02815260206004820152601960248201527f4f7261636c6520707269636520666565646572206f6e6c792e00000000000000604482015290519081900360640190fd5b600160a060020a0381161515611d9657600080fd5b60098054600160a060020a031916600160a060020a0392909216919091179055565b600754600090600160a060020a03163314611e0b576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206123f8833981519152604482015290519081900360640190fd5b60648410158015611e1c5750606483115b1515611e72576040805160e560020a62461bcd02815260206004820152600d60248201527f496e76616c696420726174657300000000000000000000000000000000000000604482015290519081900360640190fd5b828411611ec9576040805160e560020a62461bcd02815260206004820152601560248201527f496e76616c6964206465706f7369742072617465730000000000000000000000604482015290519081900360640190fd5b838211611f20576040805160e560020a62461bcd02815260206004820152601460248201527f496e76616c696420726563616c6c207261746573000000000000000000000000604482015290519081900360640190fd5b6008546040805160e060020a63a3ff31b5028152600160a060020a0388811660048301529151919092169163a3ff31b59160248083019260209291908290030181600087803b158015611f7257600080fd5b505af1158015611f86573d6000803e3d6000fd5b505050506040513d6020811015611f9c57600080fd5b505180611fb25750600160a060020a0385166001145b9050801515611ff9576040805160e560020a62461bcd0281526020600482015260126024820152600080516020612418833981519152604482015290519081900360640190fd5b604080516060810182528581526020808201868152828401868152600160a060020a038a16600090815260018085529086902094518555915191840191909155516002928301558154835181830281018301909452808452612099939291830182828015611b7c57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311611b5e575050505050866122bb565b15156120eb57600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018054600160a060020a031916600160a060020a0387161790555b5050505050565b600160a060020a03918216600090815260016020818152604080842094909516835260039093019092529190912080549101549091565b600160a060020a03811660009081526020818152604080832080546001820180548451818702810187019095528085526060958695869561ffff9095169460028101936003909101928591908301828280156121ae57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311612190575b505050505092508180548060200260200160405190810160405280929190818152602001828054801561220057602002820191906000526020600020905b8154815260200190600101908083116121ec575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561225c57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161223e575b5050505050905093509350935093509193509193565b6000805b83518110156122af5782848281518110151561228e57fe5b9060200190602002015114156122a757600191506122b4565b600101612276565b600091505b5092915050565b6000805b83518110156122af5782600160a060020a031684828151811015156122e057fe5b90602001906020020151600160a060020a0316141561230257600191506122b4565b6001016122bf565b82805482825590600052602060002090810192821561235f579160200282015b8281111561235f5782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019061232a565b5061236b9291506123b6565b5090565b8280548282559060005260206000209081019282156123aa579160200282015b828111156123aa57825182559160200191906001019061238f565b5061236b9291506123dd565b6123da91905b8082111561236b578054600160a060020a03191681556001016123bc565b90565b6123da91905b8082111561236b57600081556001016123e356004d6f64657261746f72206f6e6c792e0000000000000000000000000000000000496e76616c696420636f6c6c61746572616c0000000000000000000000000000a165627a7a72305820c96a7844fbc99f6cd5124b4b98c05fdfa83bae82c294c9ecae7cce94364056950029`
+
+// DeployLending deploys a new Ethereum contract, binding an instance of Lending to it.
+func DeployLending(auth *bind.TransactOpts, backend bind.ContractBackend, r common.Address, t common.Address) (common.Address, *types.Transaction, *Lending, error) {
+ parsed, err := abi.JSON(strings.NewReader(LendingABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(LendingBin), backend, r, t)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &Lending{LendingCaller: LendingCaller{contract: contract}, LendingTransactor: LendingTransactor{contract: contract}, LendingFilterer: LendingFilterer{contract: contract}}, nil
+}
+
+// Lending is an auto generated Go binding around an Ethereum contract.
+type Lending struct {
+ LendingCaller // Read-only binding to the contract
+ LendingTransactor // Write-only binding to the contract
+ LendingFilterer // Log filterer for contract events
+}
+
+// LendingCaller is an auto generated read-only Go binding around an Ethereum contract.
+type LendingCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LendingTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type LendingTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LendingFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type LendingFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// LendingSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type LendingSession struct {
+ Contract *Lending // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LendingCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type LendingCallerSession struct {
+ Contract *LendingCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// LendingTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type LendingTransactorSession struct {
+ Contract *LendingTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// LendingRaw is an auto generated low-level Go binding around an Ethereum contract.
+type LendingRaw struct {
+ Contract *Lending // Generic contract binding to access the raw methods on
+}
+
+// LendingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type LendingCallerRaw struct {
+ Contract *LendingCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// LendingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type LendingTransactorRaw struct {
+ Contract *LendingTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewLending creates a new instance of Lending, bound to a specific deployed contract.
+func NewLending(address common.Address, backend bind.ContractBackend) (*Lending, error) {
+ contract, err := bindLending(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &Lending{LendingCaller: LendingCaller{contract: contract}, LendingTransactor: LendingTransactor{contract: contract}, LendingFilterer: LendingFilterer{contract: contract}}, nil
+}
+
+// NewLendingCaller creates a new read-only instance of Lending, bound to a specific deployed contract.
+func NewLendingCaller(address common.Address, caller bind.ContractCaller) (*LendingCaller, error) {
+ contract, err := bindLending(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LendingCaller{contract: contract}, nil
+}
+
+// NewLendingTransactor creates a new write-only instance of Lending, bound to a specific deployed contract.
+func NewLendingTransactor(address common.Address, transactor bind.ContractTransactor) (*LendingTransactor, error) {
+ contract, err := bindLending(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LendingTransactor{contract: contract}, nil
+}
+
+// NewLendingFilterer creates a new log filterer instance of Lending, bound to a specific deployed contract.
+func NewLendingFilterer(address common.Address, filterer bind.ContractFilterer) (*LendingFilterer, error) {
+ contract, err := bindLending(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &LendingFilterer{contract: contract}, nil
+}
+
+// bindLending binds a generic wrapper to an already deployed contract.
+func bindLending(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(LendingABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Lending *LendingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Lending.Contract.LendingCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Lending *LendingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Lending.Contract.LendingTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Lending *LendingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Lending.Contract.LendingTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Lending *LendingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Lending.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Lending *LendingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Lending.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Lending *LendingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Lending.Contract.contract.Transact(opts, method, params...)
+}
+
+// BASES is a free data retrieval call binding the contract method 0x6d1dc42a.
+//
+// Solidity: function BASES( uint256) constant returns(address)
+func (_Lending *LendingCaller) BASES(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "BASES", arg0)
+ return *ret0, err
+}
+
+// BASES is a free data retrieval call binding the contract method 0x6d1dc42a.
+//
+// Solidity: function BASES( uint256) constant returns(address)
+func (_Lending *LendingSession) BASES(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.BASES(&_Lending.CallOpts, arg0)
+}
+
+// BASES is a free data retrieval call binding the contract method 0x6d1dc42a.
+//
+// Solidity: function BASES( uint256) constant returns(address)
+func (_Lending *LendingCallerSession) BASES(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.BASES(&_Lending.CallOpts, arg0)
+}
+
+// COLLATERALS is a free data retrieval call binding the contract method 0x0811f05a.
+//
+// Solidity: function COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingCaller) COLLATERALS(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "COLLATERALS", arg0)
+ return *ret0, err
+}
+
+// COLLATERALS is a free data retrieval call binding the contract method 0x0811f05a.
+//
+// Solidity: function COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingSession) COLLATERALS(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.COLLATERALS(&_Lending.CallOpts, arg0)
+}
+
+// COLLATERALS is a free data retrieval call binding the contract method 0x0811f05a.
+//
+// Solidity: function COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingCallerSession) COLLATERALS(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.COLLATERALS(&_Lending.CallOpts, arg0)
+}
+
+// COLLATERALLIST is a free data retrieval call binding the contract method 0x82250701.
+//
+// Solidity: function COLLATERAL_LIST( address) constant returns(_depositRate uint256, _liquidationRate uint256, _recallRate uint256)
+func (_Lending *LendingCaller) COLLATERALLIST(opts *bind.CallOpts, arg0 common.Address) (struct {
+ DepositRate *big.Int
+ LiquidationRate *big.Int
+ RecallRate *big.Int
+}, error) {
+ ret := new(struct {
+ DepositRate *big.Int
+ LiquidationRate *big.Int
+ RecallRate *big.Int
+ })
+ out := ret
+ err := _Lending.contract.Call(opts, out, "COLLATERAL_LIST", arg0)
+ return *ret, err
+}
+
+// COLLATERALLIST is a free data retrieval call binding the contract method 0x82250701.
+//
+// Solidity: function COLLATERAL_LIST( address) constant returns(_depositRate uint256, _liquidationRate uint256, _recallRate uint256)
+func (_Lending *LendingSession) COLLATERALLIST(arg0 common.Address) (struct {
+ DepositRate *big.Int
+ LiquidationRate *big.Int
+ RecallRate *big.Int
+}, error) {
+ return _Lending.Contract.COLLATERALLIST(&_Lending.CallOpts, arg0)
+}
+
+// COLLATERALLIST is a free data retrieval call binding the contract method 0x82250701.
+//
+// Solidity: function COLLATERAL_LIST( address) constant returns(_depositRate uint256, _liquidationRate uint256, _recallRate uint256)
+func (_Lending *LendingCallerSession) COLLATERALLIST(arg0 common.Address) (struct {
+ DepositRate *big.Int
+ LiquidationRate *big.Int
+ RecallRate *big.Int
+}, error) {
+ return _Lending.Contract.COLLATERALLIST(&_Lending.CallOpts, arg0)
+}
+
+// ILOCOLLATERALS is a free data retrieval call binding the contract method 0xb8687ec4.
+//
+// Solidity: function ILO_COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingCaller) ILOCOLLATERALS(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "ILO_COLLATERALS", arg0)
+ return *ret0, err
+}
+
+// ILOCOLLATERALS is a free data retrieval call binding the contract method 0xb8687ec4.
+//
+// Solidity: function ILO_COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingSession) ILOCOLLATERALS(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.ILOCOLLATERALS(&_Lending.CallOpts, arg0)
+}
+
+// ILOCOLLATERALS is a free data retrieval call binding the contract method 0xb8687ec4.
+//
+// Solidity: function ILO_COLLATERALS( uint256) constant returns(address)
+func (_Lending *LendingCallerSession) ILOCOLLATERALS(arg0 *big.Int) (common.Address, error) {
+ return _Lending.Contract.ILOCOLLATERALS(&_Lending.CallOpts, arg0)
+}
+
+// LENDINGRELAYERLIST is a free data retrieval call binding the contract method 0x0faf292c.
+//
+// Solidity: function LENDINGRELAYER_LIST( address) constant returns(_tradeFee uint16)
+func (_Lending *LendingCaller) LENDINGRELAYERLIST(opts *bind.CallOpts, arg0 common.Address) (uint16, error) {
+ var (
+ ret0 = new(uint16)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "LENDINGRELAYER_LIST", arg0)
+ return *ret0, err
+}
+
+// LENDINGRELAYERLIST is a free data retrieval call binding the contract method 0x0faf292c.
+//
+// Solidity: function LENDINGRELAYER_LIST( address) constant returns(_tradeFee uint16)
+func (_Lending *LendingSession) LENDINGRELAYERLIST(arg0 common.Address) (uint16, error) {
+ return _Lending.Contract.LENDINGRELAYERLIST(&_Lending.CallOpts, arg0)
+}
+
+// LENDINGRELAYERLIST is a free data retrieval call binding the contract method 0x0faf292c.
+//
+// Solidity: function LENDINGRELAYER_LIST( address) constant returns(_tradeFee uint16)
+func (_Lending *LendingCallerSession) LENDINGRELAYERLIST(arg0 common.Address) (uint16, error) {
+ return _Lending.Contract.LENDINGRELAYERLIST(&_Lending.CallOpts, arg0)
+}
+
+// MODERATOR is a free data retrieval call binding the contract method 0x34b4e625.
+//
+// Solidity: function MODERATOR() constant returns(address)
+func (_Lending *LendingCaller) MODERATOR(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "MODERATOR")
+ return *ret0, err
+}
+
+// MODERATOR is a free data retrieval call binding the contract method 0x34b4e625.
+//
+// Solidity: function MODERATOR() constant returns(address)
+func (_Lending *LendingSession) MODERATOR() (common.Address, error) {
+ return _Lending.Contract.MODERATOR(&_Lending.CallOpts)
+}
+
+// MODERATOR is a free data retrieval call binding the contract method 0x34b4e625.
+//
+// Solidity: function MODERATOR() constant returns(address)
+func (_Lending *LendingCallerSession) MODERATOR() (common.Address, error) {
+ return _Lending.Contract.MODERATOR(&_Lending.CallOpts)
+}
+
+// ORACLEPRICEFEEDER is a free data retrieval call binding the contract method 0x0c4c2cbb.
+//
+// Solidity: function ORACLE_PRICE_FEEDER() constant returns(address)
+func (_Lending *LendingCaller) ORACLEPRICEFEEDER(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "ORACLE_PRICE_FEEDER")
+ return *ret0, err
+}
+
+// ORACLEPRICEFEEDER is a free data retrieval call binding the contract method 0x0c4c2cbb.
+//
+// Solidity: function ORACLE_PRICE_FEEDER() constant returns(address)
+func (_Lending *LendingSession) ORACLEPRICEFEEDER() (common.Address, error) {
+ return _Lending.Contract.ORACLEPRICEFEEDER(&_Lending.CallOpts)
+}
+
+// ORACLEPRICEFEEDER is a free data retrieval call binding the contract method 0x0c4c2cbb.
+//
+// Solidity: function ORACLE_PRICE_FEEDER() constant returns(address)
+func (_Lending *LendingCallerSession) ORACLEPRICEFEEDER() (common.Address, error) {
+ return _Lending.Contract.ORACLEPRICEFEEDER(&_Lending.CallOpts)
+}
+
+// Relayer is a free data retrieval call binding the contract method 0x264949d8.
+//
+// Solidity: function Relayer() constant returns(address)
+func (_Lending *LendingCaller) Relayer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "Relayer")
+ return *ret0, err
+}
+
+// Relayer is a free data retrieval call binding the contract method 0x264949d8.
+//
+// Solidity: function Relayer() constant returns(address)
+func (_Lending *LendingSession) Relayer() (common.Address, error) {
+ return _Lending.Contract.Relayer(&_Lending.CallOpts)
+}
+
+// Relayer is a free data retrieval call binding the contract method 0x264949d8.
+//
+// Solidity: function Relayer() constant returns(address)
+func (_Lending *LendingCallerSession) Relayer() (common.Address, error) {
+ return _Lending.Contract.Relayer(&_Lending.CallOpts)
+}
+
+// TERMS is a free data retrieval call binding the contract method 0x56327f57.
+//
+// Solidity: function TERMS( uint256) constant returns(uint256)
+func (_Lending *LendingCaller) TERMS(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "TERMS", arg0)
+ return *ret0, err
+}
+
+// TERMS is a free data retrieval call binding the contract method 0x56327f57.
+//
+// Solidity: function TERMS( uint256) constant returns(uint256)
+func (_Lending *LendingSession) TERMS(arg0 *big.Int) (*big.Int, error) {
+ return _Lending.Contract.TERMS(&_Lending.CallOpts, arg0)
+}
+
+// TERMS is a free data retrieval call binding the contract method 0x56327f57.
+//
+// Solidity: function TERMS( uint256) constant returns(uint256)
+func (_Lending *LendingCallerSession) TERMS(arg0 *big.Int) (*big.Int, error) {
+ return _Lending.Contract.TERMS(&_Lending.CallOpts, arg0)
+}
+
+// XDCXListing is a free data retrieval call binding the contract method 0x29a4ddec.
+//
+// Solidity: function XDCXListing() constant returns(address)
+func (_Lending *LendingCaller) XDCXListing(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _Lending.contract.Call(opts, out, "XDCXListing")
+ return *ret0, err
+}
+
+// XDCXListing is a free data retrieval call binding the contract method 0x29a4ddec.
+//
+// Solidity: function XDCXListing() constant returns(address)
+func (_Lending *LendingSession) XDCXListing() (common.Address, error) {
+ return _Lending.Contract.XDCXListing(&_Lending.CallOpts)
+}
+
+// XDCXListing is a free data retrieval call binding the contract method 0x29a4ddec.
+//
+// Solidity: function XDCXListing() constant returns(address)
+func (_Lending *LendingCallerSession) XDCXListing() (common.Address, error) {
+ return _Lending.Contract.XDCXListing(&_Lending.CallOpts)
+}
+
+// GetCollateralPrice is a free data retrieval call binding the contract method 0xf2dbd070.
+//
+// Solidity: function getCollateralPrice(token address, lendingToken address) constant returns(uint256, uint256)
+func (_Lending *LendingCaller) GetCollateralPrice(opts *bind.CallOpts, token common.Address, lendingToken common.Address) (*big.Int, *big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ ret1 = new(*big.Int)
+ )
+ out := &[]interface{}{
+ ret0,
+ ret1,
+ }
+ err := _Lending.contract.Call(opts, out, "getCollateralPrice", token, lendingToken)
+ return *ret0, *ret1, err
+}
+
+// GetCollateralPrice is a free data retrieval call binding the contract method 0xf2dbd070.
+//
+// Solidity: function getCollateralPrice(token address, lendingToken address) constant returns(uint256, uint256)
+func (_Lending *LendingSession) GetCollateralPrice(token common.Address, lendingToken common.Address) (*big.Int, *big.Int, error) {
+ return _Lending.Contract.GetCollateralPrice(&_Lending.CallOpts, token, lendingToken)
+}
+
+// GetCollateralPrice is a free data retrieval call binding the contract method 0xf2dbd070.
+//
+// Solidity: function getCollateralPrice(token address, lendingToken address) constant returns(uint256, uint256)
+func (_Lending *LendingCallerSession) GetCollateralPrice(token common.Address, lendingToken common.Address) (*big.Int, *big.Int, error) {
+ return _Lending.Contract.GetCollateralPrice(&_Lending.CallOpts, token, lendingToken)
+}
+
+// GetLendingRelayerByCoinbase is a free data retrieval call binding the contract method 0xfe824700.
+//
+// Solidity: function getLendingRelayerByCoinbase(coinbase address) constant returns(uint16, address[], uint256[], address[])
+func (_Lending *LendingCaller) GetLendingRelayerByCoinbase(opts *bind.CallOpts, coinbase common.Address) (uint16, []common.Address, []*big.Int, []common.Address, error) {
+ var (
+ ret0 = new(uint16)
+ ret1 = new([]common.Address)
+ ret2 = new([]*big.Int)
+ ret3 = new([]common.Address)
+ )
+ out := &[]interface{}{
+ ret0,
+ ret1,
+ ret2,
+ ret3,
+ }
+ err := _Lending.contract.Call(opts, out, "getLendingRelayerByCoinbase", coinbase)
+ return *ret0, *ret1, *ret2, *ret3, err
+}
+
+// GetLendingRelayerByCoinbase is a free data retrieval call binding the contract method 0xfe824700.
+//
+// Solidity: function getLendingRelayerByCoinbase(coinbase address) constant returns(uint16, address[], uint256[], address[])
+func (_Lending *LendingSession) GetLendingRelayerByCoinbase(coinbase common.Address) (uint16, []common.Address, []*big.Int, []common.Address, error) {
+ return _Lending.Contract.GetLendingRelayerByCoinbase(&_Lending.CallOpts, coinbase)
+}
+
+// GetLendingRelayerByCoinbase is a free data retrieval call binding the contract method 0xfe824700.
+//
+// Solidity: function getLendingRelayerByCoinbase(coinbase address) constant returns(uint16, address[], uint256[], address[])
+func (_Lending *LendingCallerSession) GetLendingRelayerByCoinbase(coinbase common.Address) (uint16, []common.Address, []*big.Int, []common.Address, error) {
+ return _Lending.Contract.GetLendingRelayerByCoinbase(&_Lending.CallOpts, coinbase)
+}
+
+// AddBaseToken is a paid mutator transaction binding the contract method 0x83e280d9.
+//
+// Solidity: function addBaseToken(token address) returns()
+func (_Lending *LendingTransactor) AddBaseToken(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "addBaseToken", token)
+}
+
+// AddBaseToken is a paid mutator transaction binding the contract method 0x83e280d9.
+//
+// Solidity: function addBaseToken(token address) returns()
+func (_Lending *LendingSession) AddBaseToken(token common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.AddBaseToken(&_Lending.TransactOpts, token)
+}
+
+// AddBaseToken is a paid mutator transaction binding the contract method 0x83e280d9.
+//
+// Solidity: function addBaseToken(token address) returns()
+func (_Lending *LendingTransactorSession) AddBaseToken(token common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.AddBaseToken(&_Lending.TransactOpts, token)
+}
+
+// AddCollateral is a paid mutator transaction binding the contract method 0xe5eecf68.
+//
+// Solidity: function addCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingTransactor) AddCollateral(opts *bind.TransactOpts, token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "addCollateral", token, depositRate, liquidationRate, recallRate)
+}
+
+// AddCollateral is a paid mutator transaction binding the contract method 0xe5eecf68.
+//
+// Solidity: function addCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingSession) AddCollateral(token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddCollateral(&_Lending.TransactOpts, token, depositRate, liquidationRate, recallRate)
+}
+
+// AddCollateral is a paid mutator transaction binding the contract method 0xe5eecf68.
+//
+// Solidity: function addCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingTransactorSession) AddCollateral(token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddCollateral(&_Lending.TransactOpts, token, depositRate, liquidationRate, recallRate)
+}
+
+// AddILOCollateral is a paid mutator transaction binding the contract method 0x3b874827.
+//
+// Solidity: function addILOCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingTransactor) AddILOCollateral(opts *bind.TransactOpts, token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "addILOCollateral", token, depositRate, liquidationRate, recallRate)
+}
+
+// AddILOCollateral is a paid mutator transaction binding the contract method 0x3b874827.
+//
+// Solidity: function addILOCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingSession) AddILOCollateral(token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddILOCollateral(&_Lending.TransactOpts, token, depositRate, liquidationRate, recallRate)
+}
+
+// AddILOCollateral is a paid mutator transaction binding the contract method 0x3b874827.
+//
+// Solidity: function addILOCollateral(token address, depositRate uint256, liquidationRate uint256, recallRate uint256) returns()
+func (_Lending *LendingTransactorSession) AddILOCollateral(token common.Address, depositRate *big.Int, liquidationRate *big.Int, recallRate *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddILOCollateral(&_Lending.TransactOpts, token, depositRate, liquidationRate, recallRate)
+}
+
+// AddTerm is a paid mutator transaction binding the contract method 0x0c655955.
+//
+// Solidity: function addTerm(term uint256) returns()
+func (_Lending *LendingTransactor) AddTerm(opts *bind.TransactOpts, term *big.Int) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "addTerm", term)
+}
+
+// AddTerm is a paid mutator transaction binding the contract method 0x0c655955.
+//
+// Solidity: function addTerm(term uint256) returns()
+func (_Lending *LendingSession) AddTerm(term *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddTerm(&_Lending.TransactOpts, term)
+}
+
+// AddTerm is a paid mutator transaction binding the contract method 0x0c655955.
+//
+// Solidity: function addTerm(term uint256) returns()
+func (_Lending *LendingTransactorSession) AddTerm(term *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.AddTerm(&_Lending.TransactOpts, term)
+}
+
+// ChangeModerator is a paid mutator transaction binding the contract method 0x46642921.
+//
+// Solidity: function changeModerator(moderator address) returns()
+func (_Lending *LendingTransactor) ChangeModerator(opts *bind.TransactOpts, moderator common.Address) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "changeModerator", moderator)
+}
+
+// ChangeModerator is a paid mutator transaction binding the contract method 0x46642921.
+//
+// Solidity: function changeModerator(moderator address) returns()
+func (_Lending *LendingSession) ChangeModerator(moderator common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.ChangeModerator(&_Lending.TransactOpts, moderator)
+}
+
+// ChangeModerator is a paid mutator transaction binding the contract method 0x46642921.
+//
+// Solidity: function changeModerator(moderator address) returns()
+func (_Lending *LendingTransactorSession) ChangeModerator(moderator common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.ChangeModerator(&_Lending.TransactOpts, moderator)
+}
+
+// ChangeOraclePriceFeeder is a paid mutator transaction binding the contract method 0xc38f473f.
+//
+// Solidity: function changeOraclePriceFeeder(feeder address) returns()
+func (_Lending *LendingTransactor) ChangeOraclePriceFeeder(opts *bind.TransactOpts, feeder common.Address) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "changeOraclePriceFeeder", feeder)
+}
+
+// ChangeOraclePriceFeeder is a paid mutator transaction binding the contract method 0xc38f473f.
+//
+// Solidity: function changeOraclePriceFeeder(feeder address) returns()
+func (_Lending *LendingSession) ChangeOraclePriceFeeder(feeder common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.ChangeOraclePriceFeeder(&_Lending.TransactOpts, feeder)
+}
+
+// ChangeOraclePriceFeeder is a paid mutator transaction binding the contract method 0xc38f473f.
+//
+// Solidity: function changeOraclePriceFeeder(feeder address) returns()
+func (_Lending *LendingTransactorSession) ChangeOraclePriceFeeder(feeder common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.ChangeOraclePriceFeeder(&_Lending.TransactOpts, feeder)
+}
+
+// SetCollateralPrice is a paid mutator transaction binding the contract method 0xacb8cd92.
+//
+// Solidity: function setCollateralPrice(token address, lendingToken address, price uint256) returns()
+func (_Lending *LendingTransactor) SetCollateralPrice(opts *bind.TransactOpts, token common.Address, lendingToken common.Address, price *big.Int) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "setCollateralPrice", token, lendingToken, price)
+}
+
+// SetCollateralPrice is a paid mutator transaction binding the contract method 0xacb8cd92.
+//
+// Solidity: function setCollateralPrice(token address, lendingToken address, price uint256) returns()
+func (_Lending *LendingSession) SetCollateralPrice(token common.Address, lendingToken common.Address, price *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.SetCollateralPrice(&_Lending.TransactOpts, token, lendingToken, price)
+}
+
+// SetCollateralPrice is a paid mutator transaction binding the contract method 0xacb8cd92.
+//
+// Solidity: function setCollateralPrice(token address, lendingToken address, price uint256) returns()
+func (_Lending *LendingTransactorSession) SetCollateralPrice(token common.Address, lendingToken common.Address, price *big.Int) (*types.Transaction, error) {
+ return _Lending.Contract.SetCollateralPrice(&_Lending.TransactOpts, token, lendingToken, price)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x2ddada4c.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, baseTokens address[], terms uint256[], collaterals address[]) returns()
+func (_Lending *LendingTransactor) Update(opts *bind.TransactOpts, coinbase common.Address, tradeFee uint16, baseTokens []common.Address, terms []*big.Int, collaterals []common.Address) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "update", coinbase, tradeFee, baseTokens, terms, collaterals)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x2ddada4c.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, baseTokens address[], terms uint256[], collaterals address[]) returns()
+func (_Lending *LendingSession) Update(coinbase common.Address, tradeFee uint16, baseTokens []common.Address, terms []*big.Int, collaterals []common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.Update(&_Lending.TransactOpts, coinbase, tradeFee, baseTokens, terms, collaterals)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x2ddada4c.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, baseTokens address[], terms uint256[], collaterals address[]) returns()
+func (_Lending *LendingTransactorSession) Update(coinbase common.Address, tradeFee uint16, baseTokens []common.Address, terms []*big.Int, collaterals []common.Address) (*types.Transaction, error) {
+ return _Lending.Contract.Update(&_Lending.TransactOpts, coinbase, tradeFee, baseTokens, terms, collaterals)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_Lending *LendingTransactor) UpdateFee(opts *bind.TransactOpts, coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _Lending.contract.Transact(opts, "updateFee", coinbase, tradeFee)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_Lending *LendingSession) UpdateFee(coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _Lending.Contract.UpdateFee(&_Lending.TransactOpts, coinbase, tradeFee)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_Lending *LendingTransactorSession) UpdateFee(coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _Lending.Contract.UpdateFee(&_Lending.TransactOpts, coinbase, tradeFee)
+}
diff --git a/contracts/XDCx/contract/LendingRegistration.sol b/contracts/XDCx/contract/LendingRegistration.sol
new file mode 100644
index 0000000000..2e46afcde3
--- /dev/null
+++ b/contracts/XDCx/contract/LendingRegistration.sol
@@ -0,0 +1,249 @@
+pragma solidity 0.4.24;
+
+contract LAbstractRegistration {
+ mapping(address => uint) public RESIGN_REQUESTS;
+ function getRelayerByCoinbase(address) public view returns (uint, address, uint256, uint16, address[] memory, address[] memory);
+}
+
+contract LAbstractXDCXListing {
+ function getTokenStatus(address) public view returns (bool);
+}
+
+contract LAbstractTokenTRC21 {
+ function issuer() public view returns (address);
+}
+
+contract Lending {
+
+ // @dev collateral = 0x0 => get collaterals from COLLATERALS
+ struct LendingRelayer {
+ uint16 _tradeFee;
+ address[] _baseTokens;
+ uint256[] _terms; // seconds
+ address[] _collaterals;
+ }
+
+ struct Price {
+ uint256 _price;
+ uint256 _blockNumber;
+ }
+
+ struct Collateral {
+ uint256 _depositRate;
+ uint256 _liquidationRate;
+ uint256 _recallRate;
+ mapping(address => Price) _price;
+ }
+
+ mapping(address => LendingRelayer) public LENDINGRELAYER_LIST;
+
+ mapping(address => Collateral) public COLLATERAL_LIST;
+ address[] public COLLATERALS;
+
+ address[] public BASES;
+
+ uint256[] public TERMS;
+
+ address[] public ILO_COLLATERALS;
+
+ LAbstractRegistration public Relayer;
+
+ address public MODERATOR;
+
+ address constant private XDCNative = 0x0000000000000000000000000000000000000001;
+
+ LAbstractXDCXListing public XDCXListing;
+
+ address public ORACLE_PRICE_FEEDER;
+
+ modifier oraclePriceFeederOnly() {
+ require(msg.sender == ORACLE_PRICE_FEEDER, "Oracle price feeder only.");
+ _;
+ }
+
+ modifier moderatorOnly() {
+ require(msg.sender == MODERATOR, "Moderator only.");
+ _;
+ }
+
+ function indexOf(address[] memory addrs, address target) internal pure returns (bool){
+ for (uint i = 0; i < addrs.length; i ++) {
+ if (addrs[i] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function termIndexOf(uint256[] memory terms, uint256 target) internal pure returns (bool){
+ for (uint i = 0; i < terms.length; i ++) {
+ if (terms[i] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ constructor (address r, address t) public {
+ Relayer = LAbstractRegistration(r);
+ XDCXListing = LAbstractXDCXListing(t);
+ ORACLE_PRICE_FEEDER = msg.sender;
+ MODERATOR = msg.sender;
+ }
+
+ // change Oracle Price Feeder, to support Oracle Price Service
+ function changeOraclePriceFeeder(address feeder) public oraclePriceFeederOnly {
+ require(feeder != address(0));
+ ORACLE_PRICE_FEEDER = feeder;
+ }
+
+ function changeModerator(address moderator) public moderatorOnly {
+ require(moderator != address(0));
+ MODERATOR = moderator;
+ }
+
+ // add/update depositRate liquidationRate recallRate price for collateral
+ function addCollateral(address token, uint256 depositRate, uint256 liquidationRate, uint256 recallRate) public moderatorOnly {
+ require(depositRate >= 100 && liquidationRate > 100, "Invalid rates");
+ require(depositRate > liquidationRate , "Invalid deposit rates");
+ require(recallRate > depositRate, "Invalid recall rates");
+
+ bool b = XDCXListing.getTokenStatus(token) || (token == XDCNative);
+ require(b, "Invalid collateral");
+
+ COLLATERAL_LIST[token] = Collateral({
+ _depositRate: depositRate,
+ _liquidationRate: liquidationRate,
+ _recallRate: recallRate
+ });
+
+ if (!indexOf(COLLATERALS, token)) {
+ COLLATERALS.push(token);
+ }
+ }
+
+ // update price for collateral
+ function setCollateralPrice(address token, address lendingToken, uint256 price) public {
+
+ bool b = XDCXListing.getTokenStatus(token) || (token == XDCNative);
+ require(b, "Invalid collateral");
+
+ require(indexOf(BASES, lendingToken), "Invalid lending token");
+
+ require(COLLATERAL_LIST[token]._depositRate >= 100, "Invalid collateral");
+
+ if (indexOf(COLLATERALS, token)) {
+ require(msg.sender == ORACLE_PRICE_FEEDER, "Oracle Price Feeder required");
+ } else {
+ LAbstractTokenTRC21 t = LAbstractTokenTRC21(token);
+ require(t.issuer() == msg.sender, "Required token issuer");
+ }
+
+ COLLATERAL_LIST[token]._price[lendingToken] = Price({
+ _price: price,
+ _blockNumber: block.number
+ });
+ }
+
+ // add/update depositRate liquidationRate recall Rate price for ILO collateral
+ // ILO token is issued by a relayer
+ function addILOCollateral(address token, uint256 depositRate, uint256 liquidationRate, uint256 recallRate) public {
+ require(depositRate >= 100 && liquidationRate > 100, "Invalid rates");
+ require(depositRate > liquidationRate , "Invalid deposit rates");
+ require(recallRate > depositRate , "Invalid recall rates");
+
+ require(!indexOf(COLLATERALS, token) , "Invalid ILO collateral");
+
+ bool b = XDCXListing.getTokenStatus(token);
+ require(b, "Invalid collateral");
+
+ LAbstractTokenTRC21 t = LAbstractTokenTRC21(token);
+ require(t.issuer() == msg.sender, "Required token issuer");
+
+ COLLATERAL_LIST[token] = Collateral({
+ _depositRate: depositRate,
+ _liquidationRate: liquidationRate,
+ _recallRate: recallRate
+ });
+
+ if (!indexOf(ILO_COLLATERALS, token)) {
+ ILO_COLLATERALS.push(token);
+ }
+ }
+
+ // lending tokens
+ function addBaseToken(address token) public moderatorOnly {
+ bool b = XDCXListing.getTokenStatus(token) || (token == XDCNative);
+ require(b, "Invalid base token");
+ if (!indexOf(BASES, token)) {
+ BASES.push(token);
+ }
+ }
+
+ // period of loan
+ function addTerm(uint256 term) public moderatorOnly {
+ require(term >= 60, "Invalid term");
+
+ if (!termIndexOf(TERMS, term)) {
+ TERMS.push(term);
+ }
+ }
+
+ function update(address coinbase, uint16 tradeFee, address[] memory baseTokens, uint256[] memory terms, address[] memory collaterals) public {
+ (, address owner,,,,) = Relayer.getRelayerByCoinbase(coinbase);
+ require(owner == msg.sender, "Relayer owner required");
+ require(Relayer.RESIGN_REQUESTS(coinbase) == 0, "Relayer required to close");
+ require(tradeFee >= 0 && tradeFee < 1000, "Invalid trade Fee"); // 0% -> 10%
+ require(baseTokens.length == terms.length, "Not valid number of terms");
+ require(baseTokens.length == collaterals.length, "Not valid number of collaterals");
+
+ // validate baseTokens
+ bool b = false;
+ for (uint i = 0; i < baseTokens.length; i++) {
+ b = indexOf(BASES, baseTokens[i]);
+ require(b == true, "Invalid lending token");
+ }
+
+ // validate terms
+ for (i = 0; i < terms.length; i++) {
+ b = termIndexOf(TERMS, terms[i]);
+ require(b == true, "Invalid term");
+ }
+
+ // validate collaterals
+ for (i = 0; i < collaterals.length; i++) {
+ if (collaterals[i] != address(0)) {
+ require(indexOf(ILO_COLLATERALS, collaterals[i]), "Invalid collateral");
+ }
+ }
+
+ LENDINGRELAYER_LIST[coinbase] = LendingRelayer({
+ _tradeFee: tradeFee,
+ _baseTokens: baseTokens,
+ _terms: terms,
+ _collaterals: collaterals
+ });
+ }
+
+ function updateFee(address coinbase, uint16 tradeFee) public {
+ (, address owner,,,,) = Relayer.getRelayerByCoinbase(coinbase);
+ require(owner == msg.sender, "Relayer owner required");
+ require(Relayer.RESIGN_REQUESTS(coinbase) == 0, "Relayer required to close");
+ require(tradeFee >= 0 && tradeFee < 1000, "Invalid trade Fee"); // 0% -> 10%
+
+ LENDINGRELAYER_LIST[coinbase]._tradeFee = tradeFee;
+ }
+
+
+ function getLendingRelayerByCoinbase(address coinbase) public view returns (uint16, address[] memory, uint256[] memory, address[] memory) {
+ return (LENDINGRELAYER_LIST[coinbase]._tradeFee,
+ LENDINGRELAYER_LIST[coinbase]._baseTokens,
+ LENDINGRELAYER_LIST[coinbase]._terms,
+ LENDINGRELAYER_LIST[coinbase]._collaterals);
+ }
+
+ function getCollateralPrice(address token, address lendingToken) public view returns (uint256, uint256) {
+ return (COLLATERAL_LIST[token]._price[lendingToken]._price,
+ COLLATERAL_LIST[token]._price[lendingToken]._blockNumber);
+ }
+}
diff --git a/contracts/XDCx/contract/Registration.go b/contracts/XDCx/contract/Registration.go
new file mode 100644
index 0000000000..ac1fb78889
--- /dev/null
+++ b/contracts/XDCx/contract/Registration.go
@@ -0,0 +1,2253 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+)
+
+// AbstractXDCXListingABI is the input ABI used to generate the binding from.
+const AbstractXDCXListingABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"getTokenStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
+
+// AbstractXDCXListingBin is the compiled bytecode used for deploying new contracts.
+const AbstractXDCXListingBin = `0x`
+
+// DeployAbstractXDCXListing deploys a new Ethereum contract, binding an instance of AbstractXDCXListing to it.
+func DeployAbstractXDCXListing(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *AbstractXDCXListing, error) {
+ parsed, err := abi.JSON(strings.NewReader(AbstractXDCXListingABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(AbstractXDCXListingBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &AbstractXDCXListing{AbstractXDCXListingCaller: AbstractXDCXListingCaller{contract: contract}, AbstractXDCXListingTransactor: AbstractXDCXListingTransactor{contract: contract}, AbstractXDCXListingFilterer: AbstractXDCXListingFilterer{contract: contract}}, nil
+}
+
+// AbstractXDCXListing is an auto generated Go binding around an Ethereum contract.
+type AbstractXDCXListing struct {
+ AbstractXDCXListingCaller // Read-only binding to the contract
+ AbstractXDCXListingTransactor // Write-only binding to the contract
+ AbstractXDCXListingFilterer // Log filterer for contract events
+}
+
+// AbstractXDCXListingCaller is an auto generated read-only Go binding around an Ethereum contract.
+type AbstractXDCXListingCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractXDCXListingTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type AbstractXDCXListingTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractXDCXListingFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type AbstractXDCXListingFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractXDCXListingSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type AbstractXDCXListingSession struct {
+ Contract *AbstractXDCXListing // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// AbstractXDCXListingCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type AbstractXDCXListingCallerSession struct {
+ Contract *AbstractXDCXListingCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// AbstractXDCXListingTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type AbstractXDCXListingTransactorSession struct {
+ Contract *AbstractXDCXListingTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// AbstractXDCXListingRaw is an auto generated low-level Go binding around an Ethereum contract.
+type AbstractXDCXListingRaw struct {
+ Contract *AbstractXDCXListing // Generic contract binding to access the raw methods on
+}
+
+// AbstractXDCXListingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type AbstractXDCXListingCallerRaw struct {
+ Contract *AbstractXDCXListingCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// AbstractXDCXListingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type AbstractXDCXListingTransactorRaw struct {
+ Contract *AbstractXDCXListingTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewAbstractXDCXListing creates a new instance of AbstractXDCXListing, bound to a specific deployed contract.
+func NewAbstractXDCXListing(address common.Address, backend bind.ContractBackend) (*AbstractXDCXListing, error) {
+ contract, err := bindAbstractXDCXListing(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractXDCXListing{AbstractXDCXListingCaller: AbstractXDCXListingCaller{contract: contract}, AbstractXDCXListingTransactor: AbstractXDCXListingTransactor{contract: contract}, AbstractXDCXListingFilterer: AbstractXDCXListingFilterer{contract: contract}}, nil
+}
+
+// NewAbstractXDCXListingCaller creates a new read-only instance of AbstractXDCXListing, bound to a specific deployed contract.
+func NewAbstractXDCXListingCaller(address common.Address, caller bind.ContractCaller) (*AbstractXDCXListingCaller, error) {
+ contract, err := bindAbstractXDCXListing(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractXDCXListingCaller{contract: contract}, nil
+}
+
+// NewAbstractXDCXListingTransactor creates a new write-only instance of AbstractXDCXListing, bound to a specific deployed contract.
+func NewAbstractXDCXListingTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractXDCXListingTransactor, error) {
+ contract, err := bindAbstractXDCXListing(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractXDCXListingTransactor{contract: contract}, nil
+}
+
+// NewAbstractXDCXListingFilterer creates a new log filterer instance of AbstractXDCXListing, bound to a specific deployed contract.
+func NewAbstractXDCXListingFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractXDCXListingFilterer, error) {
+ contract, err := bindAbstractXDCXListing(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractXDCXListingFilterer{contract: contract}, nil
+}
+
+// bindAbstractXDCXListing binds a generic wrapper to an already deployed contract.
+func bindAbstractXDCXListing(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(AbstractXDCXListingABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AbstractXDCXListing *AbstractXDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _AbstractXDCXListing.Contract.AbstractXDCXListingCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AbstractXDCXListing *AbstractXDCXListingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _AbstractXDCXListing.Contract.AbstractXDCXListingTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AbstractXDCXListing *AbstractXDCXListingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _AbstractXDCXListing.Contract.AbstractXDCXListingTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AbstractXDCXListing *AbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _AbstractXDCXListing.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AbstractXDCXListing *AbstractXDCXListingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _AbstractXDCXListing.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AbstractXDCXListing *AbstractXDCXListingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _AbstractXDCXListing.Contract.contract.Transact(opts, method, params...)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_AbstractXDCXListing *AbstractXDCXListingCaller) GetTokenStatus(opts *bind.CallOpts, arg0 common.Address) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _AbstractXDCXListing.contract.Call(opts, out, "getTokenStatus", arg0)
+ return *ret0, err
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_AbstractXDCXListing *AbstractXDCXListingSession) GetTokenStatus(arg0 common.Address) (bool, error) {
+ return _AbstractXDCXListing.Contract.GetTokenStatus(&_AbstractXDCXListing.CallOpts, arg0)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus( address) constant returns(bool)
+func (_AbstractXDCXListing *AbstractXDCXListingCallerSession) GetTokenStatus(arg0 common.Address) (bool, error) {
+ return _AbstractXDCXListing.Contract.GetTokenStatus(&_AbstractXDCXListing.CallOpts, arg0)
+}
+
+// RelayerRegistrationABI is the input ABI used to generate the binding from.
+const RelayerRegistrationABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"fromToken\",\"type\":\"address\"},{\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"listToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MaximumRelayers\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"tradeFee\",\"type\":\"uint16\"}],\"name\":\"updateFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"changeContractOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"RELAYER_LIST\",\"outputs\":[{\"name\":\"_deposit\",\"type\":\"uint256\"},{\"name\":\"_tradeFee\",\"type\":\"uint16\"},{\"name\":\"_index\",\"type\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"depositMore\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"RELAYER_COINBASES\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"RESIGN_REQUESTS\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"getRelayerByCoinbase\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint16\"},{\"name\":\"\",\"type\":\"address[]\"},{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"name\":\"fromTokens\",\"type\":\"address[]\"},{\"name\":\"toTokens\",\"type\":\"address[]\"}],\"name\":\"update\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"maxRelayer\",\"type\":\"uint256\"},{\"name\":\"maxToken\",\"type\":\"uint256\"},{\"name\":\"minDeposit\",\"type\":\"uint256\"}],\"name\":\"reconfigure\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"cancelSelling\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ActiveRelayerCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"fromToken\",\"type\":\"address\"},{\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"deListToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"sellRelayer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"RelayerCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"RELAYER_ON_SALE_LIST\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"resign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"new_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MinimumDeposit\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"},{\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"name\":\"fromTokens\",\"type\":\"address[]\"},{\"name\":\"toTokens\",\"type\":\"address[]\"}],\"name\":\"register\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MaximumTokenList\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"buyRelayer\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"coinbase\",\"type\":\"address\"}],\"name\":\"refund\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"CONTRACT_OWNER\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"XDCxListing\",\"type\":\"address\"},{\"name\":\"maxRelayers\",\"type\":\"uint256\"},{\"name\":\"maxTokenList\",\"type\":\"uint256\"},{\"name\":\"minDeposit\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"max_relayer\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"max_token\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"min_deposit\",\"type\":\"uint256\"}],\"name\":\"ConfigEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"fromTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"name\":\"toTokens\",\"type\":\"address[]\"}],\"name\":\"RegisterEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"fromTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"name\":\"toTokens\",\"type\":\"address[]\"}],\"name\":\"UpdateEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"coinbase\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tradeFee\",\"type\":\"uint16\"}],\"name\":\"UpdateFeeEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"deposit\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tradeFee\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"fromTokens\",\"type\":\"address[]\"},{\"indexed\":false,\"name\":\"toTokens\",\"type\":\"address[]\"}],\"name\":\"TransferEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"deposit_release_time\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"deposit_amount\",\"type\":\"uint256\"}],\"name\":\"ResignEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"remaining_time\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"deposit_amount\",\"type\":\"uint256\"}],\"name\":\"RefundEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"is_on_sale\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"coinbase\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"SellEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"coinbase\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"BuyEvent\",\"type\":\"event\"}]"
+
+// RelayerRegistrationBin is the compiled bytecode used for deploying new contracts.
+const RelayerRegistrationBin = `0x608060405234801561001057600080fd5b50604051608080613d298339810160409081528151602083015191830151606090930151600a8054600160a060020a03909316600160a060020a0319938416179055600060078190556009819055600193909355600293909355600892909255805490911633179055613ca1806100886000396000f30060806040526004361061012f5763ffffffff60e060020a60003504166308764b9d81146101345780630e5c0fee146101635780633ea2391f1461018a5780633ead67b5146101b257806349ba1f70146101d35780634ce69bf5146102265780634fa339271461023a578063500f99f71461026e578063540105c71461028f57806356246b681461037f57806357ea3c41146104235780635b673b1f14610441578063735db683146104625780637aa667301461047757806387c6bbcd146104a457806387d340ab146104c8578063885b7137146104dd578063ae6e43f5146104fe578063ba45b0b81461051f578063c635a9f214610546578063c6c71aed1461055b578063cfaece12146105f2578063e699df0e14610607578063fa89401a1461061b578063fd301c491461063c575b600080fd5b34801561014057600080fd5b50610161600160a060020a0360043581169060243581169060443516610651565b005b34801561016f57600080fd5b506101786109c1565b60408051918252519081900360200190f35b34801561019657600080fd5b50610161600160a060020a036004351661ffff602435166109c7565b3480156101be57600080fd5b50610161600160a060020a0360043516610bf0565b3480156101df57600080fd5b506101f4600160a060020a0360043516610c89565b6040805194855261ffff909316602085015283830191909152600160a060020a03166060830152519081900360800190f35b610161600160a060020a0360043516610cbe565b34801561024657600080fd5b50610252600435611010565b60408051600160a060020a039092168252519081900360200190f35b34801561027a57600080fd5b50610178600160a060020a036004351661102b565b34801561029b57600080fd5b506102b0600160a060020a036004351661103d565b6040518087815260200186600160a060020a0316600160a060020a031681526020018581526020018461ffff1661ffff1681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561032657818101518382015260200161030e565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561036557818101518382015260200161034d565b505050509050019850505050505050505060405180910390f35b34801561038b57600080fd5b506040805160206004604435818101358381028086018501909652808552610161958335600160a060020a0316956024803561ffff1696369695606495939492019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506111509650505050505050565b34801561042f57600080fd5b50610161600435602435604435611595565b34801561044d57600080fd5b50610161600160a060020a0360043516611684565b34801561046e57600080fd5b50610178611850565b34801561048357600080fd5b50610161600160a060020a0360043581169060243581169060443516611856565b3480156104b057600080fd5b50610161600160a060020a0360043516602435611b79565b3480156104d457600080fd5b50610178611d30565b3480156104e957600080fd5b50610178600160a060020a0360043516611d36565b34801561050a57600080fd5b50610161600160a060020a0360043516611d48565b34801561052b57600080fd5b50610161600160a060020a0360043581169060243516611f94565b34801561055257600080fd5b506101786122dc565b6040805160206004604435818101358381028086018501909652808552610161958335600160a060020a0316956024803561ffff1696369695606495939492019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506122e29650505050505050565b3480156105fe57600080fd5b5061017861299f565b610161600160a060020a03600435166129a5565b34801561062757600080fd5b50610161600160a060020a0360043516612c5e565b34801561064857600080fd5b50610252612f7b565b600160a060020a0383811660009081526003602052604090206005015484911633146106b5576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038416600090815260056020526040902054849015610727576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a038516600090815260066020526040902054859015610799576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b60028054600160a060020a0388166000908152600360205260409020909101541061080e576040805160e560020a62461bcd02815260206004820152601f60248201527f457863656564696e67206e756d626572206f6620747261646520706169727300604482015290519081900360640190fd5b610819868686612f8a565b1515600114610872576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c696420706169720000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0380871660008181526003602081815260408084206002810180546001818101835582885285882090910180548f8b16600160a060020a031991821617909155958301805480830182558189528689200180549a8f169a909716999099179095559590945283549290930154835183815261ffff90911691810182905260809381018481528554948201859052600080516020613c168339815191529693959294929392606083019060a08401908690801561095e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610940575b505083810382528481815481526020019150805480156109a757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610989575b5050965050505050505060405180910390a1505050505050565b60015481565b600160a060020a038281166000908152600360205260409020600501548391163314610a2b576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038316600090815260056020526040902054839015610a9d576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a038416600090815260066020526040902054849015610b0f576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b60008461ffff1610158015610b2957506103e88461ffff16105b1515610b7f576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c6964204d616b657220466565000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038516600081815260036020908152604091829020600101805461ffff191661ffff89811691909117918290558351948552169083015280517f5a4f79c1a68f4f5ef7148ac4f279a5a6caeb3237082c64f692e92c9e02ffc4599281900390910190a15050505050565b600054600160a060020a03163314610c52576040805160e560020a62461bcd02815260206004820152601460248201527f436f6e7472616374204f776e6572204f6e6c792e000000000000000000000000604482015290519081900360640190fd5b600160a060020a0381161515610c6757600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b6003602052600090815260409020805460018201546004830154600590930154919261ffff90911691600160a060020a031684565b600160a060020a038181166000908152600360205260409020600501548291163314610d22576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038216600090815260056020526040902054829015610d94576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a038316600090815260066020526040902054839015610e06576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b60003411610e5e576040805160e560020a62461bcd02815260206004820152601a60248201527f5472616e736665722076616c7565206d757374206265203e2030000000000000604482015290519081900360640190fd5b670de0b6b3a7640000341015610ee4576040805160e560020a62461bcd02815260206004820152603160248201527f4174206c65617374203120544f4d4f20697320726571756972656420666f722060448201527f61206465706f7369742072657175657374000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a038416600090815260036020526040902054610f0d903463ffffffff61333c16565b600160a060020a0385166000908152600360208181526040928390208481556001810154845186815261ffff9091169281018390526080948101858152600283018054968301879052600080516020613c16833981519152979694959094930192606083019060a084019086908015610faf57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f91575b50508381038252848181548152602001915080548015610ff857602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610fda575b5050965050505050505060405180910390a150505050565b600460205260009081526040902054600160a060020a031681565b60056020526000908152604090205481565b600160a060020a03808216600090815260036020818152604080842060048101546005820154825460018401546002850180548751818a0281018a01909852808852999a8b9a8b9a8b9a60609a8b9a989094169761ffff90961695909101929184918301828280156110d857602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116110ba575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561113457602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611116575b5050505050905095509550955095509550955091939550919395565b600160a060020a0384811660009081526003602052604090206005015485911633146111b4576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038516600090815260056020526040902054859015611226576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a038616600090815260066020526040902054869015611298576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b60008661ffff16101580156112b257506103e88661ffff16105b1515611308576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c6964204d616b657220466565000000000000000000000000000000604482015290519081900360640190fd5b60025485511115611363576040805160e560020a62461bcd02815260206004820152601f60248201527f457863656564696e67206e756d626572206f6620747261646520706169727300604482015290519081900360640190fd5b84518451146113bc576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f742076616c6964206e756d626572206f6620506169727300000000000000604482015290519081900360640190fd5b6113c68585613359565b151560011461141f576040805160e560020a62461bcd02815260206004820152601460248201527f496e76616c69642071756f746520746f6b656e73000000000000000000000000604482015290519081900360640190fd5b600160a060020a038716600090815260036020908152604090912060018101805461ffff191661ffff8a16179055865161146192600290920191880190613aee565b50600160a060020a0387166000908152600360208181526040909220865161149193919092019190870190613aee565b50600160a060020a03871660009081526003602081815260409283902080546001820154855182815261ffff9091169381018490526080958101868152600284018054978301889052600080516020613c1683398151915297939690940192606083019060a08401908690801561153157602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611513575b5050838103825284818154815260200191508054801561157a57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161155c575b5050965050505050505060405180910390a150505050505050565b600054600160a060020a031633146115f7576040805160e560020a62461bcd02815260206004820152601460248201527f436f6e7472616374204f776e6572204f6e6c792e000000000000000000000000604482015290519081900360640190fd5b60095483101561160657600080fd5b60048211801561161757506103e982105b151561162257600080fd5b612710811161163057600080fd5b600183905560028290556008819055604080518481526020810184905280820183905290517f8f6bd709a98381db4e403a67ba106d598972dad177e946f19b54777f54d939239181900360600190a1505050565b600160a060020a0381811660009081526003602052604090206005015482911633146116e8576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a03821660009081526005602052604090205482901561175a576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a038316600090815260066020526040812054116117ee576040805160e560020a62461bcd02815260206004820152602160248201527f52656c61796572206973206e6f742063757272656e746c7920666f722073616c60448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03831660008181526006602090815260408083208390558051838152918201939093528083019190915290517fdb3d5e65fcde89731529c01d62b87bab1c64471cffdd528fc1adbc1712b5d0829181900360600190a1505050565b60095481565b600160a060020a03838116600090815260036020526040902060050154606091829186911633146118bf576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038616600090815260056020526040902054869015611931576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a0387166000908152600660205260409020548790156119a3576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b6119ae888888613718565b945094506119bc8585613359565b1515600114611a15576040805160e560020a62461bcd02815260206004820152601460248201527f496e76616c69642071756f746520746f6b656e73000000000000000000000000604482015290519081900360640190fd5b600160a060020a03881660009081526003602090815260409091208651611a4492600290920191880190613aee565b50600160a060020a03881660009081526003602081815260409092208651611a7493919092019190870190613aee565b50600160a060020a03881660009081526003602081815260409283902080546001820154855182815261ffff9091169381018490526080958101868152600284018054978301889052600080516020613c1683398151915297939690940192606083019060a084019086908015611b1457602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611af6575b50508381038252848181548152602001915080548015611b5d57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611b3f575b5050965050505050505060405180910390a15050505050505050565b600160a060020a038281166000908152600360205260409020600501548391163314611bdd576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038316600090815260056020526040902054839015611c4f576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b60008311611ccd576040805160e560020a62461bcd02815260206004820152602860248201527f507269636520746167206d75737420626520646966666572656e74207468616e60448201527f205a65726f283029000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03841660008181526006602090815260409182902086905581516001815290810192909252818101859052517fdb3d5e65fcde89731529c01d62b87bab1c64471cffdd528fc1adbc1712b5d0829181900360600190a150505050565b60075481565b60066020526000908152604090205481565b600160a060020a038181166000908152600360205260409020600501548291163314611dac576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038216600090815260066020526040902054829015611e1e576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b600160a060020a03831660009081526003602052604081205411611eb2576040805160e560020a62461bcd02815260206004820152602760248201527f4e6f2072656c61796572206173736f636961746564207769746820746869732060448201527f6164647265737300000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03831660009081526005602052604090205415611f20576040805160e560020a62461bcd02815260206004820152601860248201527f5265717565737420616c72656164792072656365697665640000000000000000604482015290519081900360640190fd5b600160a060020a03831660009081526005602090815260408083206224ea0042018155600980546000190190555460038352928190205481519384529183019190915280517f2e821a4329d6351a6b13fe0c12fd7674cd0f4a2283685a4713e1325f36415ae59281900390910190a1505050565b600160a060020a038281166000908152600360205260409020600501548391163314611ff8576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a03831660009081526005602052604090205483901561206a576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a0384166000908152600660205260409020548490156120dc576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b600160a060020a038416158015906120fd5750600160a060020a0384163314155b151561210857600080fd5b600160a060020a0384811660009081526003602052604090206005015416156121a1576040805160e560020a62461bcd02815260206004820152603c60248201527f4f776e65722061646472657373206d757374206e6f742062652063757272656e60448201527f746c7920757365642061732072656c617965722d636f696e6261736500000000606482015290519081900360840190fd5b600160a060020a03858116600090815260036020818152604092839020600581018054600160a060020a0319168a871617908190558154600183015486519290971680835293820181905261ffff90961694810185905260a0606082018181526002840180549284018390527fc13ab794f75ba420a1f52192a8e35a2cf2c74ae31ed94f53f47ce7712011b66298959795969094019291608083019060c08401908690801561227957602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161225b575b505083810382528481815481526020019150805480156122c257602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116122a4575b505097505050505050505060405180910390a15050505050565b60085481565b600054600160a060020a031633141561236b576040805160e560020a62461bcd02815260206004820152602f60248201527f436f6e7472616374204f776e657220697320666f7262696464656e20746f206360448201527f726561746520612052656c617965720000000000000000000000000000000000606482015290519081900360840190fd5b33600160a060020a03851614156123f2576040805160e560020a62461bcd02815260206004820152603660248201527f436f696e6261736520616e642052656c617965724f776e65722061646472657360448201527f73206d757374206e6f74206265207468652073616d6500000000000000000000606482015290519081900360840190fd5b600054600160a060020a038581169116141561247e576040805160e560020a62461bcd02815260206004820152602b60248201527f436f696e62617365206d757374206e6f742062652073616d6520617320434f4e60448201527f54524143545f4f574e4552000000000000000000000000000000000000000000606482015290519081900360840190fd5b6008543410156124d8576040805160e560020a62461bcd02815260206004820152601e60248201527f4d696e696d756d206465706f736974206e6f74207361746973666965642e0000604482015290519081900360640190fd5b60008361ffff16101580156124f257506103e88361ffff16105b1515612548576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c6964204d616b657220466565000000000000000000000000000000604482015290519081900360640190fd5b600254825111156125a3576040805160e560020a62461bcd02815260206004820152601f60248201527f457863656564696e67206e756d626572206f6620747261646520706169727300604482015290519081900360640190fd5b81518151146125fc576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f742076616c6964206e756d626572206f6620506169727300000000000000604482015290519081900360640190fd5b600160a060020a0384166000908152600360205260409020541561266a576040805160e560020a62461bcd02815260206004820152601c60248201527f436f696e6261736520616c726561647920726567697374657265642e00000000604482015290519081900360640190fd5b600160a060020a038416600090815260056020526040902054156126da576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b60015460095410612735576040805160e560020a62461bcd02815260206004820152601b60248201527f4d6178696d756d2072656c617965727320726567697374657265640000000000604482015290519081900360640190fd5b61273f8282613359565b1515600114612798576040805160e560020a62461bcd02815260206004820152601460248201527f496e76616c69642071756f746520746f6b656e73000000000000000000000000604482015290519081900360640190fd5b6007805460009081526004602090815260408083208054600160a060020a031916600160a060020a038a16908117909155815160c08101835234815261ffff8981168286019081528285018a8152606084018a9052975460808401523360a0840152928652600385529290942084518155905160018201805461ffff19169190931617909155925180519293926128359260028501920190613aee565b5060608201518051612851916003840191602090910190613aee565b50608082810151600483015560a09283015160059092018054600160a060020a031916600160a060020a039384161790556007805460019081019091556009805482019055918716600090815260036020818152604092839020805495810154845187815261ffff9091169281018390529384018581526002820180549686018790527fcf24380d990b0bb3dd21518926bca48f81495ac131ee92655696db28c43b1b1b9893969095929094019391929091606084019184019086908015610faf57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610f915750508381038252848181548152602001915080548015610ff857602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610fda575050965050505050505060405180910390a150505050565b60025481565b600160a060020a0381166000908152600560205260408120548190839015612a19576040805160e560020a62461bcd0281526020600482015260286024820152600080516020613bd68339815191526044820152600080516020613c36833981519152606482015290519081900360840190fd5b600160a060020a03841660009081526006602052604081205493508311612ab0576040805160e560020a62461bcd02815260206004820152602160248201527f52656c61796572206973206e6f742063757272656e746c7920666f722073616c60448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b348314612b07576040805160e560020a62461bcd02815260206004820152601960248201527f50726963652d746167206d757374206265206d61746368656400000000000000604482015290519081900360640190fd5b600160a060020a038085166000908152600360205260409020600501541691503315801590612b3f575033600160a060020a03831614155b8015612b535750600160a060020a03821615155b1515612ba9576040805160e560020a62461bcd02815260206004820152601160248201527f41646472657373206e6f742076616c6964000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0380851660009081526003602090815260408083206005018054600160a060020a031916331790556006909152808220829055519184169185156108fc0291869190818181858888f19350505050158015612c0f573d6000803e3d6000fd5b506040805160018152600160a060020a0386166020820152348183015290517f07e248a3b3d2184a9491c3b45089a6e15aac742b9d974e691e7beb0f6e7c58c69181900360600190a150505050565b600160a060020a038181166000908152600360205260408120600501549091829182918591163314612cc8576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613bb6833981519152604482015290519081900360640190fd5b600160a060020a038516600090815260066020526040902054859015612d3a576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613bf68339815191526044820152600080516020613c56833981519152606482015290519081900360840190fd5b600160a060020a03861660009081526005602052604081205411612da8576040805160e560020a62461bcd02815260206004820152601160248201527f52657175657374206e6f7420666f756e64000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0386166000908152600360209081526040808320805460049091015460059093529220549196509450421115612f1657600160a060020a038616600090815260036020526040812081815560018101805461ffff1916905590612e156002830182613b53565b612e23600383016000613b53565b506000600482810182905560059283018054600160a060020a0319908116909155600160a060020a038a811684526020948552604080852085905560078054600019908101875285885282872080548087169091558c88528388208054919095169516851790935583865260039096528085209093018990558454019093555191945033916108fc88150291889190818181858888f19350505050158015612ecf573d6000803e3d6000fd5b5060408051600181526000602082015280820187905290517ffaba1aac53309af4c1c439f38c29500d3828405ee1ca5e7641b0432d17d302509181900360600190a1612f73565b600160a060020a038616600090815260056020908152604080832054815193845242900391830191909152818101879052517ffaba1aac53309af4c1c439f38c29500d3828405ee1ca5e7641b0432d17d302509181900360600190a15b505050505050565b600054600160a060020a031681565b600160a060020a0383166000908152600360208181526040808420909201548251600190910180825280830282019092019092528291606091839182918015612fdd578160200160208202803883390190505b50600a54604080517fa3ff31b5000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152915193965091169163a3ff31b5916024808201926020929091908290030181600087803b15801561304857600080fd5b505af115801561305c573d6000803e3d6000fd5b505050506040513d602081101561307257600080fd5b5051806130885750600160a060020a0386166001145b915081801561313a5750600a54604080517fa3ff31b5000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301529151919092169163a3ff31b59160248083019260209291908290030181600087803b1580156130fa57600080fd5b505af115801561310e573d6000803e3d6000fd5b505050506040513d602081101561312457600080fd5b50518061313a5750600160a060020a0387166001145b915081151561314c5760009450613331565b600160a060020a0387166001148061316d5750600160a060020a0386166001145b1561317b5760019450613331565b5060005b600160a060020a0388166000908152600360208190526040909120015481101561331357600160a060020a038816600090815260036020819052604090912001805460019190839081106131cf57fe5b600091825260209091200154600160a060020a0316141561325957600160a060020a038816600090815260036020526040902060020180548290811061321157fe5b6000918252602090912001548351600160a060020a039091169084908690811061323757fe5b600160a060020a0390921660209283029091019091015260019093019261330b565b600160a060020a03881660009081526003602052604090206002018054600191908390811061328457fe5b600091825260209091200154600160a060020a0316141561330b57600160a060020a0388166000908152600360208190526040909120018054829081106132c757fe5b6000918252602090912001548351600160a060020a03909116908490869081106132ed57fe5b600160a060020a039092166020928302909101909101526001909301925b60010161317f565b61331d8387613a95565b151561332c5760009450613331565b600194505b505050509392505050565b60008282018381101561334e57600080fd5b8091505b5092915050565b60008060006060806000806000809650600095508951604051908082528060200260200182016040528015613398578160200160208202803883390190505b50945089516040519080825280602002602001820160405280156133c6578160200160208202803883390190505b509350600092505b88518310156136c257600a548951600160a060020a039091169063a3ff31b5908b90869081106133fa57fe5b906020019060200201516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561344f57600080fd5b505af1158015613463573d6000803e3d6000fd5b505050506040513d602081101561347957600080fd5b5051806134a7575088516001908a908590811061349257fe5b90602001906020020151600160a060020a0316145b91508180156135815750600a548a51600160a060020a039091169063a3ff31b5908c90869081106134d457fe5b906020019060200201516040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561352957600080fd5b505af115801561353d573d6000803e3d6000fd5b505050506040513d602081101561355357600080fd5b505180613581575089516001908b908590811061356c57fe5b90602001906020020151600160a060020a0316145b9150811515613593576000975061370b565b88516001908a90859081106135a457fe5b90602001906020020151600160a060020a031614156136055789838151811015156135cb57fe5b9060200190602002015185888151811015156135e357fe5b600160a060020a039092166020928302909101909101526001909601956136b7565b89516001908b908590811061361657fe5b90602001906020020151600160a060020a0316141561367357888381518110151561363d57fe5b90602001906020020151858881518110151561365557fe5b600160a060020a039092166020928302909101909101526001909601955b888381518110151561368157fe5b90602001906020020151848781518110151561369957fe5b600160a060020a039092166020928302909101909101526001909501945b6001909201916133ce565b5060005b85811015613706576136ef8585838151811015156136e057fe5b90602001906020020151613a95565b15156136fe576000975061370b565b6001016136c6565b600197505b5050505050505092915050565b6060806060806000806060806000600360008d600160a060020a0316600160a060020a031681526020019081526020016000206003018054905060405190808252806020026020018201604052801561377b578160200160208202803883390190505b50600160a060020a038d16600090815260036020818152604092839020909101548251818152818302810190920190925291985080156137c5578160200160208202803883390190505b50955060009450600093505b600160a060020a038c166000908152600360208190526040909120015484101561395c57600160a060020a038c81166000908152600360208190526040909120018054918c16918690811061382257fe5b600091825260209091200154600160a060020a03161415806138835750600160a060020a038c811660009081526003602052604090206002018054918d16918690811061386b57fe5b600091825260209091200154600160a060020a031614155b1561395157600160a060020a038c1660009081526003602052604090206002018054859081106138af57fe5b6000918252602090912001548751600160a060020a03909116908890879081106138d557fe5b600160a060020a039283166020918202909201810191909152908d166000908152600391829052604090200180548590811061390d57fe5b6000918252602090912001548651600160a060020a039091169087908790811061393357fe5b600160a060020a039092166020928302909101909101526001909401935b6001909301926137d1565b600160a060020a038c16600090815260036020819052604090912001548514613a7f5760018651036040519080825280602002602001820160405280156139ad578160200160208202803883390190505b50925060018651036040519080825280602002602001820160405280156139de578160200160208202803883390190505b509150600090505b6001865103811015613a74578681815181101515613a0057fe5b906020019060200201518382815181101515613a1857fe5b600160a060020a039092166020928302909101909101528551869082908110613a3d57fe5b906020019060200201518282815181101515613a5557fe5b600160a060020a039092166020928302909101909101526001016139e6565b828298509850613a86565b8686985098505b50505050505050935093915050565b6000805b8351811015613ae45782600160a060020a03168482815181101515613aba57fe5b90602001906020020151600160a060020a03161415613adc5760019150613352565b600101613a99565b5060009392505050565b828054828255906000526020600020908101928215613b43579160200282015b82811115613b435782518254600160a060020a031916600160a060020a03909116178255602090920191600190910190613b0e565b50613b4f929150613b74565b5090565b5080546000825590600052602060002090810190613b719190613b9b565b50565b613b9891905b80821115613b4f578054600160a060020a0319168155600101613b7a565b90565b613b9891905b80821115613b4f5760008155600101613ba1560052656c61796572204f776e6572204f6e6c792e000000000000000000000000005468652072656c6179657220686173206265656e2072657175657374656420745468652072656c61796572206d757374206265206e6f742063757272656e746ccaa8c94daf6ecfd00518cea95158f5273730574cca907eb0cd47e50732314c4f6f20636c6f73652e0000000000000000000000000000000000000000000000007920666f722053616c6500000000000000000000000000000000000000000000a165627a7a723058207d9c49eecfd59b2ae9911da7296be4a9f5e5d938cbf3dfb6327f454bc1c46a4f0029`
+
+// DeployRelayerRegistration deploys a new Ethereum contract, binding an instance of RelayerRegistration to it.
+func DeployRelayerRegistration(auth *bind.TransactOpts, backend bind.ContractBackend, XDCxListing common.Address, maxRelayers *big.Int, maxTokenList *big.Int, minDeposit *big.Int) (common.Address, *types.Transaction, *RelayerRegistration, error) {
+ parsed, err := abi.JSON(strings.NewReader(RelayerRegistrationABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(RelayerRegistrationBin), backend, XDCxListing, maxRelayers, maxTokenList, minDeposit)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &RelayerRegistration{RelayerRegistrationCaller: RelayerRegistrationCaller{contract: contract}, RelayerRegistrationTransactor: RelayerRegistrationTransactor{contract: contract}, RelayerRegistrationFilterer: RelayerRegistrationFilterer{contract: contract}}, nil
+}
+
+// RelayerRegistration is an auto generated Go binding around an Ethereum contract.
+type RelayerRegistration struct {
+ RelayerRegistrationCaller // Read-only binding to the contract
+ RelayerRegistrationTransactor // Write-only binding to the contract
+ RelayerRegistrationFilterer // Log filterer for contract events
+}
+
+// RelayerRegistrationCaller is an auto generated read-only Go binding around an Ethereum contract.
+type RelayerRegistrationCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// RelayerRegistrationTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type RelayerRegistrationTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// RelayerRegistrationFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type RelayerRegistrationFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// RelayerRegistrationSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type RelayerRegistrationSession struct {
+ Contract *RelayerRegistration // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// RelayerRegistrationCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type RelayerRegistrationCallerSession struct {
+ Contract *RelayerRegistrationCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// RelayerRegistrationTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type RelayerRegistrationTransactorSession struct {
+ Contract *RelayerRegistrationTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// RelayerRegistrationRaw is an auto generated low-level Go binding around an Ethereum contract.
+type RelayerRegistrationRaw struct {
+ Contract *RelayerRegistration // Generic contract binding to access the raw methods on
+}
+
+// RelayerRegistrationCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type RelayerRegistrationCallerRaw struct {
+ Contract *RelayerRegistrationCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// RelayerRegistrationTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type RelayerRegistrationTransactorRaw struct {
+ Contract *RelayerRegistrationTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewRelayerRegistration creates a new instance of RelayerRegistration, bound to a specific deployed contract.
+func NewRelayerRegistration(address common.Address, backend bind.ContractBackend) (*RelayerRegistration, error) {
+ contract, err := bindRelayerRegistration(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistration{RelayerRegistrationCaller: RelayerRegistrationCaller{contract: contract}, RelayerRegistrationTransactor: RelayerRegistrationTransactor{contract: contract}, RelayerRegistrationFilterer: RelayerRegistrationFilterer{contract: contract}}, nil
+}
+
+// NewRelayerRegistrationCaller creates a new read-only instance of RelayerRegistration, bound to a specific deployed contract.
+func NewRelayerRegistrationCaller(address common.Address, caller bind.ContractCaller) (*RelayerRegistrationCaller, error) {
+ contract, err := bindRelayerRegistration(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationCaller{contract: contract}, nil
+}
+
+// NewRelayerRegistrationTransactor creates a new write-only instance of RelayerRegistration, bound to a specific deployed contract.
+func NewRelayerRegistrationTransactor(address common.Address, transactor bind.ContractTransactor) (*RelayerRegistrationTransactor, error) {
+ contract, err := bindRelayerRegistration(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationTransactor{contract: contract}, nil
+}
+
+// NewRelayerRegistrationFilterer creates a new log filterer instance of RelayerRegistration, bound to a specific deployed contract.
+func NewRelayerRegistrationFilterer(address common.Address, filterer bind.ContractFilterer) (*RelayerRegistrationFilterer, error) {
+ contract, err := bindRelayerRegistration(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationFilterer{contract: contract}, nil
+}
+
+// bindRelayerRegistration binds a generic wrapper to an already deployed contract.
+func bindRelayerRegistration(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(RelayerRegistrationABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_RelayerRegistration *RelayerRegistrationRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _RelayerRegistration.Contract.RelayerRegistrationCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_RelayerRegistration *RelayerRegistrationRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.RelayerRegistrationTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_RelayerRegistration *RelayerRegistrationRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.RelayerRegistrationTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_RelayerRegistration *RelayerRegistrationCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _RelayerRegistration.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_RelayerRegistration *RelayerRegistrationTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_RelayerRegistration *RelayerRegistrationTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.contract.Transact(opts, method, params...)
+}
+
+// ActiveRelayerCount is a free data retrieval call binding the contract method 0x735db683.
+//
+// Solidity: function ActiveRelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) ActiveRelayerCount(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "ActiveRelayerCount")
+ return *ret0, err
+}
+
+// ActiveRelayerCount is a free data retrieval call binding the contract method 0x735db683.
+//
+// Solidity: function ActiveRelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) ActiveRelayerCount() (*big.Int, error) {
+ return _RelayerRegistration.Contract.ActiveRelayerCount(&_RelayerRegistration.CallOpts)
+}
+
+// ActiveRelayerCount is a free data retrieval call binding the contract method 0x735db683.
+//
+// Solidity: function ActiveRelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) ActiveRelayerCount() (*big.Int, error) {
+ return _RelayerRegistration.Contract.ActiveRelayerCount(&_RelayerRegistration.CallOpts)
+}
+
+// CONTRACTOWNER is a free data retrieval call binding the contract method 0xfd301c49.
+//
+// Solidity: function CONTRACT_OWNER() constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationCaller) CONTRACTOWNER(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "CONTRACT_OWNER")
+ return *ret0, err
+}
+
+// CONTRACTOWNER is a free data retrieval call binding the contract method 0xfd301c49.
+//
+// Solidity: function CONTRACT_OWNER() constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationSession) CONTRACTOWNER() (common.Address, error) {
+ return _RelayerRegistration.Contract.CONTRACTOWNER(&_RelayerRegistration.CallOpts)
+}
+
+// CONTRACTOWNER is a free data retrieval call binding the contract method 0xfd301c49.
+//
+// Solidity: function CONTRACT_OWNER() constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) CONTRACTOWNER() (common.Address, error) {
+ return _RelayerRegistration.Contract.CONTRACTOWNER(&_RelayerRegistration.CallOpts)
+}
+
+// MaximumRelayers is a free data retrieval call binding the contract method 0x0e5c0fee.
+//
+// Solidity: function MaximumRelayers() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) MaximumRelayers(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "MaximumRelayers")
+ return *ret0, err
+}
+
+// MaximumRelayers is a free data retrieval call binding the contract method 0x0e5c0fee.
+//
+// Solidity: function MaximumRelayers() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) MaximumRelayers() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MaximumRelayers(&_RelayerRegistration.CallOpts)
+}
+
+// MaximumRelayers is a free data retrieval call binding the contract method 0x0e5c0fee.
+//
+// Solidity: function MaximumRelayers() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) MaximumRelayers() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MaximumRelayers(&_RelayerRegistration.CallOpts)
+}
+
+// MaximumTokenList is a free data retrieval call binding the contract method 0xcfaece12.
+//
+// Solidity: function MaximumTokenList() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) MaximumTokenList(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "MaximumTokenList")
+ return *ret0, err
+}
+
+// MaximumTokenList is a free data retrieval call binding the contract method 0xcfaece12.
+//
+// Solidity: function MaximumTokenList() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) MaximumTokenList() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MaximumTokenList(&_RelayerRegistration.CallOpts)
+}
+
+// MaximumTokenList is a free data retrieval call binding the contract method 0xcfaece12.
+//
+// Solidity: function MaximumTokenList() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) MaximumTokenList() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MaximumTokenList(&_RelayerRegistration.CallOpts)
+}
+
+// MinimumDeposit is a free data retrieval call binding the contract method 0xc635a9f2.
+//
+// Solidity: function MinimumDeposit() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) MinimumDeposit(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "MinimumDeposit")
+ return *ret0, err
+}
+
+// MinimumDeposit is a free data retrieval call binding the contract method 0xc635a9f2.
+//
+// Solidity: function MinimumDeposit() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) MinimumDeposit() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MinimumDeposit(&_RelayerRegistration.CallOpts)
+}
+
+// MinimumDeposit is a free data retrieval call binding the contract method 0xc635a9f2.
+//
+// Solidity: function MinimumDeposit() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) MinimumDeposit() (*big.Int, error) {
+ return _RelayerRegistration.Contract.MinimumDeposit(&_RelayerRegistration.CallOpts)
+}
+
+// RELAYERCOINBASES is a free data retrieval call binding the contract method 0x4fa33927.
+//
+// Solidity: function RELAYER_COINBASES( uint256) constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERCOINBASES(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_COINBASES", arg0)
+ return *ret0, err
+}
+
+// RELAYERCOINBASES is a free data retrieval call binding the contract method 0x4fa33927.
+//
+// Solidity: function RELAYER_COINBASES( uint256) constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationSession) RELAYERCOINBASES(arg0 *big.Int) (common.Address, error) {
+ return _RelayerRegistration.Contract.RELAYERCOINBASES(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RELAYERCOINBASES is a free data retrieval call binding the contract method 0x4fa33927.
+//
+// Solidity: function RELAYER_COINBASES( uint256) constant returns(address)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) RELAYERCOINBASES(arg0 *big.Int) (common.Address, error) {
+ return _RelayerRegistration.Contract.RELAYERCOINBASES(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RELAYERLIST is a free data retrieval call binding the contract method 0x49ba1f70.
+//
+// Solidity: function RELAYER_LIST( address) constant returns(_deposit uint256, _tradeFee uint16, _index uint256, _owner address)
+func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERLIST(opts *bind.CallOpts, arg0 common.Address) (struct {
+ Deposit *big.Int
+ TradeFee uint16
+ Index *big.Int
+ Owner common.Address
+}, error) {
+ ret := new(struct {
+ Deposit *big.Int
+ TradeFee uint16
+ Index *big.Int
+ Owner common.Address
+ })
+ out := ret
+ err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_LIST", arg0)
+ return *ret, err
+}
+
+// RELAYERLIST is a free data retrieval call binding the contract method 0x49ba1f70.
+//
+// Solidity: function RELAYER_LIST( address) constant returns(_deposit uint256, _tradeFee uint16, _index uint256, _owner address)
+func (_RelayerRegistration *RelayerRegistrationSession) RELAYERLIST(arg0 common.Address) (struct {
+ Deposit *big.Int
+ TradeFee uint16
+ Index *big.Int
+ Owner common.Address
+}, error) {
+ return _RelayerRegistration.Contract.RELAYERLIST(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RELAYERLIST is a free data retrieval call binding the contract method 0x49ba1f70.
+//
+// Solidity: function RELAYER_LIST( address) constant returns(_deposit uint256, _tradeFee uint16, _index uint256, _owner address)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) RELAYERLIST(arg0 common.Address) (struct {
+ Deposit *big.Int
+ TradeFee uint16
+ Index *big.Int
+ Owner common.Address
+}, error) {
+ return _RelayerRegistration.Contract.RELAYERLIST(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RELAYERONSALELIST is a free data retrieval call binding the contract method 0x885b7137.
+//
+// Solidity: function RELAYER_ON_SALE_LIST( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERONSALELIST(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_ON_SALE_LIST", arg0)
+ return *ret0, err
+}
+
+// RELAYERONSALELIST is a free data retrieval call binding the contract method 0x885b7137.
+//
+// Solidity: function RELAYER_ON_SALE_LIST( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) RELAYERONSALELIST(arg0 common.Address) (*big.Int, error) {
+ return _RelayerRegistration.Contract.RELAYERONSALELIST(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RELAYERONSALELIST is a free data retrieval call binding the contract method 0x885b7137.
+//
+// Solidity: function RELAYER_ON_SALE_LIST( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) RELAYERONSALELIST(arg0 common.Address) (*big.Int, error) {
+ return _RelayerRegistration.Contract.RELAYERONSALELIST(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) RESIGNREQUESTS(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "RESIGN_REQUESTS", arg0)
+ return *ret0, err
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) RESIGNREQUESTS(arg0 common.Address) (*big.Int, error) {
+ return _RelayerRegistration.Contract.RESIGNREQUESTS(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RESIGNREQUESTS is a free data retrieval call binding the contract method 0x500f99f7.
+//
+// Solidity: function RESIGN_REQUESTS( address) constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) RESIGNREQUESTS(arg0 common.Address) (*big.Int, error) {
+ return _RelayerRegistration.Contract.RESIGNREQUESTS(&_RelayerRegistration.CallOpts, arg0)
+}
+
+// RelayerCount is a free data retrieval call binding the contract method 0x87d340ab.
+//
+// Solidity: function RelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCaller) RelayerCount(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _RelayerRegistration.contract.Call(opts, out, "RelayerCount")
+ return *ret0, err
+}
+
+// RelayerCount is a free data retrieval call binding the contract method 0x87d340ab.
+//
+// Solidity: function RelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationSession) RelayerCount() (*big.Int, error) {
+ return _RelayerRegistration.Contract.RelayerCount(&_RelayerRegistration.CallOpts)
+}
+
+// RelayerCount is a free data retrieval call binding the contract method 0x87d340ab.
+//
+// Solidity: function RelayerCount() constant returns(uint256)
+func (_RelayerRegistration *RelayerRegistrationCallerSession) RelayerCount() (*big.Int, error) {
+ return _RelayerRegistration.Contract.RelayerCount(&_RelayerRegistration.CallOpts)
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase(coinbase address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_RelayerRegistration *RelayerRegistrationCaller) GetRelayerByCoinbase(opts *bind.CallOpts, coinbase common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ var (
+ ret0 = new(*big.Int)
+ ret1 = new(common.Address)
+ ret2 = new(*big.Int)
+ ret3 = new(uint16)
+ ret4 = new([]common.Address)
+ ret5 = new([]common.Address)
+ )
+ out := &[]interface{}{
+ ret0,
+ ret1,
+ ret2,
+ ret3,
+ ret4,
+ ret5,
+ }
+ err := _RelayerRegistration.contract.Call(opts, out, "getRelayerByCoinbase", coinbase)
+ return *ret0, *ret1, *ret2, *ret3, *ret4, *ret5, err
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase(coinbase address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_RelayerRegistration *RelayerRegistrationSession) GetRelayerByCoinbase(coinbase common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ return _RelayerRegistration.Contract.GetRelayerByCoinbase(&_RelayerRegistration.CallOpts, coinbase)
+}
+
+// GetRelayerByCoinbase is a free data retrieval call binding the contract method 0x540105c7.
+//
+// Solidity: function getRelayerByCoinbase(coinbase address) constant returns(uint256, address, uint256, uint16, address[], address[])
+func (_RelayerRegistration *RelayerRegistrationCallerSession) GetRelayerByCoinbase(coinbase common.Address) (*big.Int, common.Address, *big.Int, uint16, []common.Address, []common.Address, error) {
+ return _RelayerRegistration.Contract.GetRelayerByCoinbase(&_RelayerRegistration.CallOpts, coinbase)
+}
+
+// BuyRelayer is a paid mutator transaction binding the contract method 0xe699df0e.
+//
+// Solidity: function buyRelayer(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) BuyRelayer(opts *bind.TransactOpts, coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "buyRelayer", coinbase)
+}
+
+// BuyRelayer is a paid mutator transaction binding the contract method 0xe699df0e.
+//
+// Solidity: function buyRelayer(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) BuyRelayer(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.BuyRelayer(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// BuyRelayer is a paid mutator transaction binding the contract method 0xe699df0e.
+//
+// Solidity: function buyRelayer(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) BuyRelayer(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.BuyRelayer(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// CancelSelling is a paid mutator transaction binding the contract method 0x5b673b1f.
+//
+// Solidity: function cancelSelling(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) CancelSelling(opts *bind.TransactOpts, coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "cancelSelling", coinbase)
+}
+
+// CancelSelling is a paid mutator transaction binding the contract method 0x5b673b1f.
+//
+// Solidity: function cancelSelling(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) CancelSelling(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.CancelSelling(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// CancelSelling is a paid mutator transaction binding the contract method 0x5b673b1f.
+//
+// Solidity: function cancelSelling(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) CancelSelling(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.CancelSelling(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// ChangeContractOwner is a paid mutator transaction binding the contract method 0x3ead67b5.
+//
+// Solidity: function changeContractOwner(owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) ChangeContractOwner(opts *bind.TransactOpts, owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "changeContractOwner", owner)
+}
+
+// ChangeContractOwner is a paid mutator transaction binding the contract method 0x3ead67b5.
+//
+// Solidity: function changeContractOwner(owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) ChangeContractOwner(owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.ChangeContractOwner(&_RelayerRegistration.TransactOpts, owner)
+}
+
+// ChangeContractOwner is a paid mutator transaction binding the contract method 0x3ead67b5.
+//
+// Solidity: function changeContractOwner(owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) ChangeContractOwner(owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.ChangeContractOwner(&_RelayerRegistration.TransactOpts, owner)
+}
+
+// DeListToken is a paid mutator transaction binding the contract method 0x7aa66730.
+//
+// Solidity: function deListToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) DeListToken(opts *bind.TransactOpts, coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "deListToken", coinbase, fromToken, toToken)
+}
+
+// DeListToken is a paid mutator transaction binding the contract method 0x7aa66730.
+//
+// Solidity: function deListToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) DeListToken(coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.DeListToken(&_RelayerRegistration.TransactOpts, coinbase, fromToken, toToken)
+}
+
+// DeListToken is a paid mutator transaction binding the contract method 0x7aa66730.
+//
+// Solidity: function deListToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) DeListToken(coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.DeListToken(&_RelayerRegistration.TransactOpts, coinbase, fromToken, toToken)
+}
+
+// DepositMore is a paid mutator transaction binding the contract method 0x4ce69bf5.
+//
+// Solidity: function depositMore(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) DepositMore(opts *bind.TransactOpts, coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "depositMore", coinbase)
+}
+
+// DepositMore is a paid mutator transaction binding the contract method 0x4ce69bf5.
+//
+// Solidity: function depositMore(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) DepositMore(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.DepositMore(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// DepositMore is a paid mutator transaction binding the contract method 0x4ce69bf5.
+//
+// Solidity: function depositMore(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) DepositMore(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.DepositMore(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// ListToken is a paid mutator transaction binding the contract method 0x08764b9d.
+//
+// Solidity: function listToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) ListToken(opts *bind.TransactOpts, coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "listToken", coinbase, fromToken, toToken)
+}
+
+// ListToken is a paid mutator transaction binding the contract method 0x08764b9d.
+//
+// Solidity: function listToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) ListToken(coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.ListToken(&_RelayerRegistration.TransactOpts, coinbase, fromToken, toToken)
+}
+
+// ListToken is a paid mutator transaction binding the contract method 0x08764b9d.
+//
+// Solidity: function listToken(coinbase address, fromToken address, toToken address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) ListToken(coinbase common.Address, fromToken common.Address, toToken common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.ListToken(&_RelayerRegistration.TransactOpts, coinbase, fromToken, toToken)
+}
+
+// Reconfigure is a paid mutator transaction binding the contract method 0x57ea3c41.
+//
+// Solidity: function reconfigure(maxRelayer uint256, maxToken uint256, minDeposit uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Reconfigure(opts *bind.TransactOpts, maxRelayer *big.Int, maxToken *big.Int, minDeposit *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "reconfigure", maxRelayer, maxToken, minDeposit)
+}
+
+// Reconfigure is a paid mutator transaction binding the contract method 0x57ea3c41.
+//
+// Solidity: function reconfigure(maxRelayer uint256, maxToken uint256, minDeposit uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Reconfigure(maxRelayer *big.Int, maxToken *big.Int, minDeposit *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Reconfigure(&_RelayerRegistration.TransactOpts, maxRelayer, maxToken, minDeposit)
+}
+
+// Reconfigure is a paid mutator transaction binding the contract method 0x57ea3c41.
+//
+// Solidity: function reconfigure(maxRelayer uint256, maxToken uint256, minDeposit uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Reconfigure(maxRelayer *big.Int, maxToken *big.Int, minDeposit *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Reconfigure(&_RelayerRegistration.TransactOpts, maxRelayer, maxToken, minDeposit)
+}
+
+// Refund is a paid mutator transaction binding the contract method 0xfa89401a.
+//
+// Solidity: function refund(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Refund(opts *bind.TransactOpts, coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "refund", coinbase)
+}
+
+// Refund is a paid mutator transaction binding the contract method 0xfa89401a.
+//
+// Solidity: function refund(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Refund(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Refund(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// Refund is a paid mutator transaction binding the contract method 0xfa89401a.
+//
+// Solidity: function refund(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Refund(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Refund(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xc6c71aed.
+//
+// Solidity: function register(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Register(opts *bind.TransactOpts, coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "register", coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xc6c71aed.
+//
+// Solidity: function register(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Register(coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Register(&_RelayerRegistration.TransactOpts, coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xc6c71aed.
+//
+// Solidity: function register(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Register(coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Register(&_RelayerRegistration.TransactOpts, coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// Resign is a paid mutator transaction binding the contract method 0xae6e43f5.
+//
+// Solidity: function resign(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Resign(opts *bind.TransactOpts, coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "resign", coinbase)
+}
+
+// Resign is a paid mutator transaction binding the contract method 0xae6e43f5.
+//
+// Solidity: function resign(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Resign(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Resign(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// Resign is a paid mutator transaction binding the contract method 0xae6e43f5.
+//
+// Solidity: function resign(coinbase address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Resign(coinbase common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Resign(&_RelayerRegistration.TransactOpts, coinbase)
+}
+
+// SellRelayer is a paid mutator transaction binding the contract method 0x87c6bbcd.
+//
+// Solidity: function sellRelayer(coinbase address, price uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) SellRelayer(opts *bind.TransactOpts, coinbase common.Address, price *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "sellRelayer", coinbase, price)
+}
+
+// SellRelayer is a paid mutator transaction binding the contract method 0x87c6bbcd.
+//
+// Solidity: function sellRelayer(coinbase address, price uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) SellRelayer(coinbase common.Address, price *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.SellRelayer(&_RelayerRegistration.TransactOpts, coinbase, price)
+}
+
+// SellRelayer is a paid mutator transaction binding the contract method 0x87c6bbcd.
+//
+// Solidity: function sellRelayer(coinbase address, price uint256) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) SellRelayer(coinbase common.Address, price *big.Int) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.SellRelayer(&_RelayerRegistration.TransactOpts, coinbase, price)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xba45b0b8.
+//
+// Solidity: function transfer(coinbase address, new_owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Transfer(opts *bind.TransactOpts, coinbase common.Address, new_owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "transfer", coinbase, new_owner)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xba45b0b8.
+//
+// Solidity: function transfer(coinbase address, new_owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Transfer(coinbase common.Address, new_owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Transfer(&_RelayerRegistration.TransactOpts, coinbase, new_owner)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xba45b0b8.
+//
+// Solidity: function transfer(coinbase address, new_owner address) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Transfer(coinbase common.Address, new_owner common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Transfer(&_RelayerRegistration.TransactOpts, coinbase, new_owner)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x56246b68.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) Update(opts *bind.TransactOpts, coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "update", coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x56246b68.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) Update(coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Update(&_RelayerRegistration.TransactOpts, coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// Update is a paid mutator transaction binding the contract method 0x56246b68.
+//
+// Solidity: function update(coinbase address, tradeFee uint16, fromTokens address[], toTokens address[]) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) Update(coinbase common.Address, tradeFee uint16, fromTokens []common.Address, toTokens []common.Address) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.Update(&_RelayerRegistration.TransactOpts, coinbase, tradeFee, fromTokens, toTokens)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactor) UpdateFee(opts *bind.TransactOpts, coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _RelayerRegistration.contract.Transact(opts, "updateFee", coinbase, tradeFee)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_RelayerRegistration *RelayerRegistrationSession) UpdateFee(coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.UpdateFee(&_RelayerRegistration.TransactOpts, coinbase, tradeFee)
+}
+
+// UpdateFee is a paid mutator transaction binding the contract method 0x3ea2391f.
+//
+// Solidity: function updateFee(coinbase address, tradeFee uint16) returns()
+func (_RelayerRegistration *RelayerRegistrationTransactorSession) UpdateFee(coinbase common.Address, tradeFee uint16) (*types.Transaction, error) {
+ return _RelayerRegistration.Contract.UpdateFee(&_RelayerRegistration.TransactOpts, coinbase, tradeFee)
+}
+
+// RelayerRegistrationBuyEventIterator is returned from FilterBuyEvent and is used to iterate over the raw logs and unpacked data for BuyEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationBuyEventIterator struct {
+ Event *RelayerRegistrationBuyEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationBuyEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationBuyEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationBuyEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationBuyEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationBuyEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationBuyEvent represents a BuyEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationBuyEvent struct {
+ Success bool
+ Coinbase common.Address
+ Price *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterBuyEvent is a free log retrieval operation binding the contract event 0x07e248a3b3d2184a9491c3b45089a6e15aac742b9d974e691e7beb0f6e7c58c6.
+//
+// Solidity: event BuyEvent(success bool, coinbase address, price uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterBuyEvent(opts *bind.FilterOpts) (*RelayerRegistrationBuyEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "BuyEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationBuyEventIterator{contract: _RelayerRegistration.contract, event: "BuyEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchBuyEvent is a free log subscription operation binding the contract event 0x07e248a3b3d2184a9491c3b45089a6e15aac742b9d974e691e7beb0f6e7c58c6.
+//
+// Solidity: event BuyEvent(success bool, coinbase address, price uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchBuyEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationBuyEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "BuyEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationBuyEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "BuyEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationConfigEventIterator is returned from FilterConfigEvent and is used to iterate over the raw logs and unpacked data for ConfigEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationConfigEventIterator struct {
+ Event *RelayerRegistrationConfigEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationConfigEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationConfigEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationConfigEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationConfigEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationConfigEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationConfigEvent represents a ConfigEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationConfigEvent struct {
+ MaxRelayer *big.Int
+ MaxToken *big.Int
+ MinDeposit *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterConfigEvent is a free log retrieval operation binding the contract event 0x8f6bd709a98381db4e403a67ba106d598972dad177e946f19b54777f54d93923.
+//
+// Solidity: event ConfigEvent(max_relayer uint256, max_token uint256, min_deposit uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterConfigEvent(opts *bind.FilterOpts) (*RelayerRegistrationConfigEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "ConfigEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationConfigEventIterator{contract: _RelayerRegistration.contract, event: "ConfigEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchConfigEvent is a free log subscription operation binding the contract event 0x8f6bd709a98381db4e403a67ba106d598972dad177e946f19b54777f54d93923.
+//
+// Solidity: event ConfigEvent(max_relayer uint256, max_token uint256, min_deposit uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchConfigEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationConfigEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "ConfigEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationConfigEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "ConfigEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationRefundEventIterator is returned from FilterRefundEvent and is used to iterate over the raw logs and unpacked data for RefundEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationRefundEventIterator struct {
+ Event *RelayerRegistrationRefundEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationRefundEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationRefundEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationRefundEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationRefundEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationRefundEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationRefundEvent represents a RefundEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationRefundEvent struct {
+ Success bool
+ RemainingTime *big.Int
+ DepositAmount *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterRefundEvent is a free log retrieval operation binding the contract event 0xfaba1aac53309af4c1c439f38c29500d3828405ee1ca5e7641b0432d17d30250.
+//
+// Solidity: event RefundEvent(success bool, remaining_time uint256, deposit_amount uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterRefundEvent(opts *bind.FilterOpts) (*RelayerRegistrationRefundEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "RefundEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationRefundEventIterator{contract: _RelayerRegistration.contract, event: "RefundEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchRefundEvent is a free log subscription operation binding the contract event 0xfaba1aac53309af4c1c439f38c29500d3828405ee1ca5e7641b0432d17d30250.
+//
+// Solidity: event RefundEvent(success bool, remaining_time uint256, deposit_amount uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchRefundEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationRefundEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "RefundEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationRefundEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "RefundEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationRegisterEventIterator is returned from FilterRegisterEvent and is used to iterate over the raw logs and unpacked data for RegisterEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationRegisterEventIterator struct {
+ Event *RelayerRegistrationRegisterEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationRegisterEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationRegisterEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationRegisterEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationRegisterEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationRegisterEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationRegisterEvent represents a RegisterEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationRegisterEvent struct {
+ Deposit *big.Int
+ TradeFee uint16
+ FromTokens []common.Address
+ ToTokens []common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterRegisterEvent is a free log retrieval operation binding the contract event 0xcf24380d990b0bb3dd21518926bca48f81495ac131ee92655696db28c43b1b1b.
+//
+// Solidity: event RegisterEvent(deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterRegisterEvent(opts *bind.FilterOpts) (*RelayerRegistrationRegisterEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "RegisterEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationRegisterEventIterator{contract: _RelayerRegistration.contract, event: "RegisterEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchRegisterEvent is a free log subscription operation binding the contract event 0xcf24380d990b0bb3dd21518926bca48f81495ac131ee92655696db28c43b1b1b.
+//
+// Solidity: event RegisterEvent(deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchRegisterEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationRegisterEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "RegisterEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationRegisterEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "RegisterEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationResignEventIterator is returned from FilterResignEvent and is used to iterate over the raw logs and unpacked data for ResignEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationResignEventIterator struct {
+ Event *RelayerRegistrationResignEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationResignEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationResignEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationResignEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationResignEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationResignEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationResignEvent represents a ResignEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationResignEvent struct {
+ DepositReleaseTime *big.Int
+ DepositAmount *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterResignEvent is a free log retrieval operation binding the contract event 0x2e821a4329d6351a6b13fe0c12fd7674cd0f4a2283685a4713e1325f36415ae5.
+//
+// Solidity: event ResignEvent(deposit_release_time uint256, deposit_amount uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterResignEvent(opts *bind.FilterOpts) (*RelayerRegistrationResignEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "ResignEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationResignEventIterator{contract: _RelayerRegistration.contract, event: "ResignEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchResignEvent is a free log subscription operation binding the contract event 0x2e821a4329d6351a6b13fe0c12fd7674cd0f4a2283685a4713e1325f36415ae5.
+//
+// Solidity: event ResignEvent(deposit_release_time uint256, deposit_amount uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchResignEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationResignEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "ResignEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationResignEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "ResignEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationSellEventIterator is returned from FilterSellEvent and is used to iterate over the raw logs and unpacked data for SellEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationSellEventIterator struct {
+ Event *RelayerRegistrationSellEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationSellEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationSellEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationSellEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationSellEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationSellEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationSellEvent represents a SellEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationSellEvent struct {
+ IsOnSale bool
+ Coinbase common.Address
+ Price *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterSellEvent is a free log retrieval operation binding the contract event 0xdb3d5e65fcde89731529c01d62b87bab1c64471cffdd528fc1adbc1712b5d082.
+//
+// Solidity: event SellEvent(is_on_sale bool, coinbase address, price uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterSellEvent(opts *bind.FilterOpts) (*RelayerRegistrationSellEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "SellEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationSellEventIterator{contract: _RelayerRegistration.contract, event: "SellEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchSellEvent is a free log subscription operation binding the contract event 0xdb3d5e65fcde89731529c01d62b87bab1c64471cffdd528fc1adbc1712b5d082.
+//
+// Solidity: event SellEvent(is_on_sale bool, coinbase address, price uint256)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchSellEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationSellEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "SellEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationSellEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "SellEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationTransferEventIterator is returned from FilterTransferEvent and is used to iterate over the raw logs and unpacked data for TransferEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationTransferEventIterator struct {
+ Event *RelayerRegistrationTransferEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationTransferEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationTransferEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationTransferEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationTransferEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationTransferEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationTransferEvent represents a TransferEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationTransferEvent struct {
+ Owner common.Address
+ Deposit *big.Int
+ TradeFee uint16
+ FromTokens []common.Address
+ ToTokens []common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransferEvent is a free log retrieval operation binding the contract event 0xc13ab794f75ba420a1f52192a8e35a2cf2c74ae31ed94f53f47ce7712011b662.
+//
+// Solidity: event TransferEvent(owner address, deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterTransferEvent(opts *bind.FilterOpts) (*RelayerRegistrationTransferEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "TransferEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationTransferEventIterator{contract: _RelayerRegistration.contract, event: "TransferEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchTransferEvent is a free log subscription operation binding the contract event 0xc13ab794f75ba420a1f52192a8e35a2cf2c74ae31ed94f53f47ce7712011b662.
+//
+// Solidity: event TransferEvent(owner address, deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchTransferEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationTransferEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "TransferEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationTransferEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "TransferEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationUpdateEventIterator is returned from FilterUpdateEvent and is used to iterate over the raw logs and unpacked data for UpdateEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationUpdateEventIterator struct {
+ Event *RelayerRegistrationUpdateEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationUpdateEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationUpdateEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationUpdateEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationUpdateEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationUpdateEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationUpdateEvent represents a UpdateEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationUpdateEvent struct {
+ Deposit *big.Int
+ TradeFee uint16
+ FromTokens []common.Address
+ ToTokens []common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterUpdateEvent is a free log retrieval operation binding the contract event 0xcaa8c94daf6ecfd00518cea95158f5273730574cca907eb0cd47e50732314c4f.
+//
+// Solidity: event UpdateEvent(deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterUpdateEvent(opts *bind.FilterOpts) (*RelayerRegistrationUpdateEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "UpdateEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationUpdateEventIterator{contract: _RelayerRegistration.contract, event: "UpdateEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchUpdateEvent is a free log subscription operation binding the contract event 0xcaa8c94daf6ecfd00518cea95158f5273730574cca907eb0cd47e50732314c4f.
+//
+// Solidity: event UpdateEvent(deposit uint256, tradeFee uint16, fromTokens address[], toTokens address[])
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchUpdateEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationUpdateEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "UpdateEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationUpdateEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "UpdateEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// RelayerRegistrationUpdateFeeEventIterator is returned from FilterUpdateFeeEvent and is used to iterate over the raw logs and unpacked data for UpdateFeeEvent events raised by the RelayerRegistration contract.
+type RelayerRegistrationUpdateFeeEventIterator struct {
+ Event *RelayerRegistrationUpdateFeeEvent // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *RelayerRegistrationUpdateFeeEventIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationUpdateFeeEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(RelayerRegistrationUpdateFeeEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *RelayerRegistrationUpdateFeeEventIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *RelayerRegistrationUpdateFeeEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// RelayerRegistrationUpdateFeeEvent represents a UpdateFeeEvent event raised by the RelayerRegistration contract.
+type RelayerRegistrationUpdateFeeEvent struct {
+ Coinbase common.Address
+ TradeFee uint16
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterUpdateFeeEvent is a free log retrieval operation binding the contract event 0x5a4f79c1a68f4f5ef7148ac4f279a5a6caeb3237082c64f692e92c9e02ffc459.
+//
+// Solidity: event UpdateFeeEvent(coinbase address, tradeFee uint16)
+func (_RelayerRegistration *RelayerRegistrationFilterer) FilterUpdateFeeEvent(opts *bind.FilterOpts) (*RelayerRegistrationUpdateFeeEventIterator, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.FilterLogs(opts, "UpdateFeeEvent")
+ if err != nil {
+ return nil, err
+ }
+ return &RelayerRegistrationUpdateFeeEventIterator{contract: _RelayerRegistration.contract, event: "UpdateFeeEvent", logs: logs, sub: sub}, nil
+}
+
+// WatchUpdateFeeEvent is a free log subscription operation binding the contract event 0x5a4f79c1a68f4f5ef7148ac4f279a5a6caeb3237082c64f692e92c9e02ffc459.
+//
+// Solidity: event UpdateFeeEvent(coinbase address, tradeFee uint16)
+func (_RelayerRegistration *RelayerRegistrationFilterer) WatchUpdateFeeEvent(opts *bind.WatchOpts, sink chan<- *RelayerRegistrationUpdateFeeEvent) (event.Subscription, error) {
+
+ logs, sub, err := _RelayerRegistration.contract.WatchLogs(opts, "UpdateFeeEvent")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(RelayerRegistrationUpdateFeeEvent)
+ if err := _RelayerRegistration.contract.UnpackLog(event, "UpdateFeeEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// SafeMathABI is the input ABI used to generate the binding from.
+const SafeMathABI = "[]"
+
+// SafeMathBin is the compiled bytecode used for deploying new contracts.
+const SafeMathBin = `0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820c6c4834061dabec64e5ceac30b20029de90ad520415e80a05c3d6dd6fae00bc80029`
+
+// DeploySafeMath deploys a new Ethereum contract, binding an instance of SafeMath to it.
+func DeploySafeMath(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SafeMath, error) {
+ parsed, err := abi.JSON(strings.NewReader(SafeMathABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(SafeMathBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &SafeMath{SafeMathCaller: SafeMathCaller{contract: contract}, SafeMathTransactor: SafeMathTransactor{contract: contract}, SafeMathFilterer: SafeMathFilterer{contract: contract}}, nil
+}
+
+// SafeMath is an auto generated Go binding around an Ethereum contract.
+type SafeMath struct {
+ SafeMathCaller // Read-only binding to the contract
+ SafeMathTransactor // Write-only binding to the contract
+ SafeMathFilterer // Log filterer for contract events
+}
+
+// SafeMathCaller is an auto generated read-only Go binding around an Ethereum contract.
+type SafeMathCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// SafeMathTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type SafeMathTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// SafeMathFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type SafeMathFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// SafeMathSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type SafeMathSession struct {
+ Contract *SafeMath // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// SafeMathCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type SafeMathCallerSession struct {
+ Contract *SafeMathCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// SafeMathTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type SafeMathTransactorSession struct {
+ Contract *SafeMathTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// SafeMathRaw is an auto generated low-level Go binding around an Ethereum contract.
+type SafeMathRaw struct {
+ Contract *SafeMath // Generic contract binding to access the raw methods on
+}
+
+// SafeMathCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type SafeMathCallerRaw struct {
+ Contract *SafeMathCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// SafeMathTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type SafeMathTransactorRaw struct {
+ Contract *SafeMathTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewSafeMath creates a new instance of SafeMath, bound to a specific deployed contract.
+func NewSafeMath(address common.Address, backend bind.ContractBackend) (*SafeMath, error) {
+ contract, err := bindSafeMath(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &SafeMath{SafeMathCaller: SafeMathCaller{contract: contract}, SafeMathTransactor: SafeMathTransactor{contract: contract}, SafeMathFilterer: SafeMathFilterer{contract: contract}}, nil
+}
+
+// NewSafeMathCaller creates a new read-only instance of SafeMath, bound to a specific deployed contract.
+func NewSafeMathCaller(address common.Address, caller bind.ContractCaller) (*SafeMathCaller, error) {
+ contract, err := bindSafeMath(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &SafeMathCaller{contract: contract}, nil
+}
+
+// NewSafeMathTransactor creates a new write-only instance of SafeMath, bound to a specific deployed contract.
+func NewSafeMathTransactor(address common.Address, transactor bind.ContractTransactor) (*SafeMathTransactor, error) {
+ contract, err := bindSafeMath(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &SafeMathTransactor{contract: contract}, nil
+}
+
+// NewSafeMathFilterer creates a new log filterer instance of SafeMath, bound to a specific deployed contract.
+func NewSafeMathFilterer(address common.Address, filterer bind.ContractFilterer) (*SafeMathFilterer, error) {
+ contract, err := bindSafeMath(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &SafeMathFilterer{contract: contract}, nil
+}
+
+// bindSafeMath binds a generic wrapper to an already deployed contract.
+func bindSafeMath(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(SafeMathABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _SafeMath.Contract.SafeMathCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_SafeMath *SafeMathRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _SafeMath.Contract.SafeMathTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_SafeMath *SafeMathRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _SafeMath.Contract.SafeMathTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _SafeMath.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_SafeMath *SafeMathTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _SafeMath.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_SafeMath *SafeMathTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _SafeMath.Contract.contract.Transact(opts, method, params...)
+}
diff --git a/contracts/XDCx/contract/Registration.sol b/contracts/XDCx/contract/Registration.sol
new file mode 100644
index 0000000000..a5eaa0025a
--- /dev/null
+++ b/contracts/XDCx/contract/Registration.sol
@@ -0,0 +1,424 @@
+pragma solidity ^0.4.24;
+
+import "./SafeMath.sol";
+
+contract AbstractXDCXListing {
+ function getTokenStatus(address) public view returns (bool);
+}
+
+contract RelayerRegistration {
+ using SafeMath for uint;
+
+ /// @dev constructor arguments
+ address public CONTRACT_OWNER;
+ uint public MaximumRelayers;
+ uint public MaximumTokenList;
+ address constant private XDCNative = 0x0000000000000000000000000000000000000001;
+
+ /// @dev Data types
+ struct Relayer {
+ uint256 _deposit;
+ uint16 _tradeFee;
+ address[] _fromTokens;
+ address[] _toTokens;
+ uint _index;
+ address _owner;
+ }
+
+ /// @DEV coinbase -> relayer
+ mapping(address => Relayer) public RELAYER_LIST;
+ /// @dev index -> coinbase
+ mapping(uint => address) public RELAYER_COINBASES;
+ /// @dev coinbase -> time
+ mapping(address => uint) public RESIGN_REQUESTS;
+ /// @dev coinbase -> price
+ mapping(address => uint256) public RELAYER_ON_SALE_LIST;
+
+ uint public RelayerCount;
+ uint256 public MinimumDeposit;
+ uint public ActiveRelayerCount;
+
+ AbstractXDCXListing private XDCXListing;
+
+ /// @dev Events
+ /// struct-mapping -> values
+ event ConfigEvent(uint max_relayer, uint max_token, uint256 min_deposit);
+ event RegisterEvent(uint256 deposit, uint16 tradeFee, address[] fromTokens, address[] toTokens);
+ event UpdateEvent(uint256 deposit, uint16 tradeFee, address[] fromTokens, address[] toTokens);
+ event UpdateFeeEvent(address coinbase, uint16 tradeFee);
+ event TransferEvent(address owner, uint256 deposit, uint16 tradeFee, address[] fromTokens, address[] toTokens);
+ event ResignEvent(uint deposit_release_time, uint256 deposit_amount);
+ event RefundEvent(bool success, uint remaining_time, uint256 deposit_amount);
+
+ event SellEvent(bool is_on_sale, address coinbase, uint256 price);
+ event BuyEvent(bool success, address coinbase, uint256 price);
+
+ constructor (address XDCxListing, uint maxRelayers, uint maxTokenList, uint minDeposit) public {
+ XDCXListing = AbstractXDCXListing(XDCxListing);
+ RelayerCount = 0;
+ ActiveRelayerCount = 0;
+ MaximumRelayers = maxRelayers;
+ MaximumTokenList = maxTokenList;
+ MinimumDeposit = minDeposit;
+ CONTRACT_OWNER = msg.sender;
+ }
+
+
+ /// @dev Modifier
+ modifier contractOwnerOnly() {
+ require(msg.sender == CONTRACT_OWNER, "Contract Owner Only.");
+ _;
+ }
+
+ modifier relayerOwnerOnly(address coinbase) {
+ require(msg.sender == RELAYER_LIST[coinbase]._owner, "Relayer Owner Only.");
+ _;
+ }
+
+ modifier onlyActiveRelayer(address coinbase) {
+ require(RESIGN_REQUESTS[coinbase] == 0, "The relayer has been requested to close.");
+ _;
+ }
+
+ modifier nonZeroValue() {
+ require(msg.value > 0, "Transfer value must be > 0");
+ _;
+ }
+
+ modifier notForSale(address coinbase) {
+ require(RELAYER_ON_SALE_LIST[coinbase] == 0, "The relayer must be not currently for Sale");
+ _;
+ }
+
+
+ /// @dev support to move to oracle service
+ function changeContractOwner(address owner) public contractOwnerOnly {
+ require(owner != address(0));
+ CONTRACT_OWNER = owner;
+ }
+
+ /// @dev Contract Config Modifications
+ function reconfigure(uint maxRelayer, uint maxToken, uint minDeposit) public contractOwnerOnly {
+ require(maxRelayer >= ActiveRelayerCount);
+ require(maxToken > 4 && maxToken < 1001);
+ require(minDeposit > 10000);
+ MaximumRelayers = maxRelayer;
+ MaximumTokenList = maxToken;
+ MinimumDeposit = minDeposit;
+
+ emit ConfigEvent(MaximumRelayers,
+ MaximumTokenList,
+ MinimumDeposit);
+ }
+
+ /// @dev State-Alter Methods
+ function register(address coinbase, uint16 tradeFee, address[] memory fromTokens, address[] memory toTokens) public payable {
+ require(msg.sender != CONTRACT_OWNER, "Contract Owner is forbidden to create a Relayer");
+ require(msg.sender != coinbase, "Coinbase and RelayerOwner address must not be the same");
+ require(coinbase != CONTRACT_OWNER, "Coinbase must not be same as CONTRACT_OWNER");
+ require(msg.value >= MinimumDeposit, "Minimum deposit not satisfied.");
+ /// @dev valid relayer configuration
+ require(tradeFee >= 0 && tradeFee < 1000, "Invalid Maker Fee");
+ require(fromTokens.length <= MaximumTokenList, "Exceeding number of trade pairs");
+ require(toTokens.length == fromTokens.length, "Not valid number of Pairs");
+
+ require(RELAYER_LIST[coinbase]._deposit == 0, "Coinbase already registered.");
+ require(RESIGN_REQUESTS[coinbase] == 0, "The relayer has been requested to close.");
+ require(ActiveRelayerCount < MaximumRelayers, "Maximum relayers registered");
+
+ // check valid tokens, token must pair with XDC(x/XDC)
+ require(validateTokens(fromTokens, toTokens) == true, "Invalid quote tokens");
+
+ RELAYER_COINBASES[RelayerCount] = coinbase;
+ RELAYER_LIST[coinbase] = Relayer({
+ _deposit: msg.value,
+ _tradeFee: tradeFee,
+ _fromTokens: fromTokens,
+ _toTokens: toTokens,
+ _index: RelayerCount,
+ _owner: msg.sender
+ });
+
+ RelayerCount++;
+ ActiveRelayerCount++;
+
+ emit RegisterEvent(RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+
+ function update(address coinbase, uint16 tradeFee, address[] memory fromTokens, address[] memory toTokens) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) {
+ require(tradeFee >= 0 && tradeFee < 1000, "Invalid Maker Fee");
+ require(fromTokens.length <= MaximumTokenList, "Exceeding number of trade pairs");
+ require(toTokens.length == fromTokens.length, "Not valid number of Pairs");
+
+ require(validateTokens(fromTokens, toTokens) == true, "Invalid quote tokens");
+
+ RELAYER_LIST[coinbase]._tradeFee = tradeFee;
+ RELAYER_LIST[coinbase]._fromTokens = fromTokens;
+ RELAYER_LIST[coinbase]._toTokens = toTokens;
+
+ emit UpdateEvent(RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+ function updateFee(address coinbase, uint16 tradeFee) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) {
+ require(tradeFee >= 0 && tradeFee < 1000, "Invalid Maker Fee");
+ RELAYER_LIST[coinbase]._tradeFee = tradeFee;
+ emit UpdateFeeEvent(coinbase, RELAYER_LIST[coinbase]._tradeFee);
+ }
+
+ // List new tokens
+ function listToken(
+ address coinbase,
+ address fromToken,
+ address toToken
+ ) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) {
+ require(RELAYER_LIST[coinbase]._fromTokens.length < MaximumTokenList, "Exceeding number of trade pairs");
+
+ require(addingTokenValidation(coinbase, fromToken, toToken) == true, "Invalid pair");
+
+ RELAYER_LIST[coinbase]._fromTokens.push(fromToken);
+ RELAYER_LIST[coinbase]._toTokens.push(toToken);
+
+ emit UpdateEvent(RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+ // delist a token
+ function deListToken(
+ address coinbase,
+ address fromToken,
+ address toToken
+ ) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) {
+ (address[] memory newFromTokens, address[] memory newToTokens) = deList(coinbase, fromToken, toToken);
+
+ require(validateTokens(newFromTokens, newToTokens) == true, "Invalid quote tokens");
+
+ RELAYER_LIST[coinbase]._fromTokens = newFromTokens;
+ RELAYER_LIST[coinbase]._toTokens = newToTokens;
+
+ emit UpdateEvent(RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+ function transfer(address coinbase, address new_owner) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) {
+ require(new_owner != address(0) && new_owner != msg.sender);
+ require(RELAYER_LIST[new_owner]._owner == address(0), "Owner address must not be currently used as relayer-coinbase");
+
+ RELAYER_LIST[coinbase]._owner = new_owner;
+ emit TransferEvent(RELAYER_LIST[coinbase]._owner,
+ RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+
+ function depositMore(address coinbase) public payable relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) notForSale(coinbase) nonZeroValue {
+ require(msg.value >= 1 ether, "At least 1 XDC is required for a deposit request");
+ RELAYER_LIST[coinbase]._deposit = RELAYER_LIST[coinbase]._deposit.add(msg.value);
+ emit UpdateEvent(RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+
+ function resign(address coinbase) public relayerOwnerOnly(coinbase) notForSale(coinbase) {
+ require(RELAYER_LIST[coinbase]._deposit > 0, "No relayer associated with this address");
+ require(RESIGN_REQUESTS[coinbase] == 0, "Request already received");
+ RESIGN_REQUESTS[coinbase] = now + 4 weeks;
+ ActiveRelayerCount--;
+ emit ResignEvent(RESIGN_REQUESTS[coinbase],
+ RELAYER_LIST[coinbase]._deposit);
+ }
+
+
+ function refund(address coinbase) public relayerOwnerOnly(coinbase) notForSale(coinbase) {
+ require(RESIGN_REQUESTS[coinbase] > 0, "Request not found");
+ uint256 amount = RELAYER_LIST[coinbase]._deposit;
+ uint deleting_index = RELAYER_LIST[coinbase]._index;
+
+ if (RESIGN_REQUESTS[coinbase] < now) {
+ delete RELAYER_LIST[coinbase];
+ delete RESIGN_REQUESTS[coinbase];
+ /// @notice swap last relayer's index with the deleting relayer's index
+ address last_coinbase = RELAYER_COINBASES[RelayerCount - 1];
+ delete RELAYER_COINBASES[RelayerCount - 1];
+
+ RELAYER_COINBASES[deleting_index] = last_coinbase;
+ RELAYER_LIST[last_coinbase]._index = deleting_index;
+
+ RelayerCount--;
+ msg.sender.transfer(amount);
+ emit RefundEvent(true,
+ 0,
+ amount);
+ } else {
+ /// Not yet, remind user about the remaining time...
+ emit RefundEvent(false,
+ RESIGN_REQUESTS[coinbase] - now,
+ amount);
+ }
+ }
+
+ /// @dev SELLING/BUYING RELAYERS
+ // NOTE: Putting a relayer on sale will immediately halt all the state-changing actions on this relayer...
+ // ...including Update, Deposit, Resign, Refund and Transfer
+ function sellRelayer(address coinbase, uint256 price) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) {
+ // NOTE: calling this function more than once will act like changing Price-tag
+ require(price > 0, "Price tag must be different than Zero(0)");
+ RELAYER_ON_SALE_LIST[coinbase] = price;
+ emit SellEvent(true, coinbase, price);
+ }
+
+ function cancelSelling(address coinbase) public relayerOwnerOnly(coinbase) onlyActiveRelayer(coinbase) {
+ require(RELAYER_ON_SALE_LIST[coinbase] > 0, "Relayer is not currently for sale");
+ delete RELAYER_ON_SALE_LIST[coinbase];
+ emit SellEvent(false, coinbase, 0);
+ }
+
+ function buyRelayer(address coinbase) public payable onlyActiveRelayer(coinbase) {
+ uint256 price = RELAYER_ON_SALE_LIST[coinbase];
+
+ require(price > 0, "Relayer is not currently for sale");
+ require(msg.value == price, "Price-tag must be matched");
+
+ address seller = RELAYER_LIST[coinbase]._owner;
+ require(msg.sender != address(0) && msg.sender != seller && seller != address(0), "Address not valid");
+ RELAYER_LIST[coinbase]._owner = msg.sender;
+
+ delete RELAYER_ON_SALE_LIST[coinbase];
+ seller.transfer(price);
+ emit BuyEvent(true, coinbase, msg.value);
+ }
+
+
+ function getRelayerByCoinbase(address coinbase) public view returns (uint, address, uint256, uint16, address[] memory, address[] memory) {
+ return (RELAYER_LIST[coinbase]._index,
+ RELAYER_LIST[coinbase]._owner,
+ RELAYER_LIST[coinbase]._deposit,
+ RELAYER_LIST[coinbase]._tradeFee,
+ RELAYER_LIST[coinbase]._fromTokens,
+ RELAYER_LIST[coinbase]._toTokens);
+ }
+
+ function indexOf(address[] memory XDCPair, address target) internal pure returns (bool){
+ for (uint i = 0; i < XDCPair.length; i ++) {
+ if (XDCPair[i] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function validateTokens(address[] memory fromTokens, address[] memory toTokens) internal returns(bool) {
+ uint countPair = 0;
+ uint countNonPair = 0;
+
+ address[] memory XDCPairs = new address[](fromTokens.length);
+ address[] memory nonXDCPairs = new address[](fromTokens.length);
+
+ for (uint i = 0; i < toTokens.length; i++) {
+ bool b = XDCXListing.getTokenStatus(toTokens[i]) || (toTokens[i] == XDCNative);
+ b = b && (XDCXListing.getTokenStatus(fromTokens[i]) || fromTokens[i] == XDCNative);
+ if (!b) {
+ return false;
+ }
+ if (toTokens[i] == XDCNative) {
+ XDCPairs[countPair] = fromTokens[i];
+ countPair++;
+ } else {
+ if (fromTokens[i] == XDCNative) {
+ XDCPairs[countPair] = toTokens[i];
+ countPair++;
+ }
+ nonXDCPairs[countNonPair] = toTokens[i];
+ countNonPair++;
+ }
+ }
+
+ for (uint j = 0; j < countNonPair; j++) {
+ if (!indexOf(XDCPairs, nonXDCPairs[j])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // add a token validation
+ function addingTokenValidation(
+ address coinbase,
+ address fromToken,
+ address toToken
+ ) internal view returns(bool){
+ uint countPair = 0;
+
+ address[] memory XDCPairs = new address[](RELAYER_LIST[coinbase]._toTokens.length + 1);
+
+ bool b = XDCXListing.getTokenStatus(toToken) || (toToken == XDCNative);
+ b = b && (XDCXListing.getTokenStatus(fromToken) || fromToken == XDCNative);
+ if (!b) {
+ return false;
+ }
+
+ if (fromToken == XDCNative || toToken == XDCNative) {
+ return true;
+ }
+
+ // get tokens that paired with XDC
+ for (uint i = 0; i < RELAYER_LIST[coinbase]._toTokens.length; i++) {
+ if (RELAYER_LIST[coinbase]._toTokens[i] == XDCNative) {
+ XDCPairs[countPair] = RELAYER_LIST[coinbase]._fromTokens[i];
+ countPair++;
+ } else {
+ if (RELAYER_LIST[coinbase]._fromTokens[i] == XDCNative) {
+ XDCPairs[countPair] = RELAYER_LIST[coinbase]._toTokens[i];
+ countPair++;
+ }
+ }
+ }
+ if (!indexOf(XDCPairs, toToken)) {
+ return false;
+ }
+ return true;
+ }
+
+ // create new arrays of base and quote tokens
+ function deList(address coinbase, address fromToken, address toToken) private view returns(address[], address[]) {
+ address[] memory newFromTokens = new address[](RELAYER_LIST[coinbase]._toTokens.length);
+ address[] memory newToTokens = new address[](RELAYER_LIST[coinbase]._toTokens.length);
+ uint count = 0;
+
+ for (uint i = 0; i < RELAYER_LIST[coinbase]._toTokens.length; i++) {
+ if (RELAYER_LIST[coinbase]._toTokens[i] != toToken ||
+ RELAYER_LIST[coinbase]._fromTokens[i] != fromToken) {
+ newFromTokens[count] = RELAYER_LIST[coinbase]._fromTokens[i];
+ newToTokens[count] = RELAYER_LIST[coinbase]._toTokens[i];
+ count++;
+ }
+ }
+
+ if (count != RELAYER_LIST[coinbase]._toTokens.length) {
+ address[] memory fts = new address[](newToTokens.length-1);
+ address[] memory tts = new address[](newToTokens.length-1);
+ for (uint j = 0; j < newToTokens.length - 1; j++) {
+ fts[j] = newFromTokens[j];
+ tts[j] = newToTokens[j];
+ }
+ return (fts, tts);
+ }
+
+ return (newFromTokens, newToTokens);
+
+ }
+}
diff --git a/contracts/XDCx/contract/SafeMath.sol b/contracts/XDCx/contract/SafeMath.sol
new file mode 100644
index 0000000000..fb3bb244e4
--- /dev/null
+++ b/contracts/XDCx/contract/SafeMath.sol
@@ -0,0 +1,61 @@
+pragma solidity ^0.4.24;
+
+library SafeMath {
+
+ /**
+ * @dev Multiplies two numbers, reverts on overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b);
+
+ return c;
+ }
+
+ /**
+ * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b > 0); // Solidity only automatically asserts when dividing by 0
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b <= a);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Adds two numbers, reverts on overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a);
+
+ return c;
+ }
+
+ /**
+ * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
+ * reverts when dividing by zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b != 0);
+ return a % b;
+ }
+}
diff --git a/contracts/XDCx/contract/TRC21.go b/contracts/XDCx/contract/TRC21.go
new file mode 100644
index 0000000000..5000083231
--- /dev/null
+++ b/contracts/XDCx/contract/TRC21.go
@@ -0,0 +1,4632 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+)
+
+// ITRC21ABI is the input ABI used to generate the binding from.
+const ITRC21ABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"estimateFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"issuer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"who\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"}]"
+
+// ITRC21Bin is the compiled bytecode used for deploying new contracts.
+const ITRC21Bin = `0x`
+
+// DeployITRC21 deploys a new Ethereum contract, binding an instance of ITRC21 to it.
+func DeployITRC21(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ITRC21, error) {
+ parsed, err := abi.JSON(strings.NewReader(ITRC21ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ITRC21Bin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &ITRC21{ITRC21Caller: ITRC21Caller{contract: contract}, ITRC21Transactor: ITRC21Transactor{contract: contract}, ITRC21Filterer: ITRC21Filterer{contract: contract}}, nil
+}
+
+// ITRC21 is an auto generated Go binding around an Ethereum contract.
+type ITRC21 struct {
+ ITRC21Caller // Read-only binding to the contract
+ ITRC21Transactor // Write-only binding to the contract
+ ITRC21Filterer // Log filterer for contract events
+}
+
+// ITRC21Caller is an auto generated read-only Go binding around an Ethereum contract.
+type ITRC21Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ITRC21Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type ITRC21Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ITRC21Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type ITRC21Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ITRC21Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ITRC21Session struct {
+ Contract *ITRC21 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ITRC21CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ITRC21CallerSession struct {
+ Contract *ITRC21Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// ITRC21TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ITRC21TransactorSession struct {
+ Contract *ITRC21Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ITRC21Raw is an auto generated low-level Go binding around an Ethereum contract.
+type ITRC21Raw struct {
+ Contract *ITRC21 // Generic contract binding to access the raw methods on
+}
+
+// ITRC21CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ITRC21CallerRaw struct {
+ Contract *ITRC21Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// ITRC21TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ITRC21TransactorRaw struct {
+ Contract *ITRC21Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewITRC21 creates a new instance of ITRC21, bound to a specific deployed contract.
+func NewITRC21(address common.Address, backend bind.ContractBackend) (*ITRC21, error) {
+ contract, err := bindITRC21(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21{ITRC21Caller: ITRC21Caller{contract: contract}, ITRC21Transactor: ITRC21Transactor{contract: contract}, ITRC21Filterer: ITRC21Filterer{contract: contract}}, nil
+}
+
+// NewITRC21Caller creates a new read-only instance of ITRC21, bound to a specific deployed contract.
+func NewITRC21Caller(address common.Address, caller bind.ContractCaller) (*ITRC21Caller, error) {
+ contract, err := bindITRC21(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21Caller{contract: contract}, nil
+}
+
+// NewITRC21Transactor creates a new write-only instance of ITRC21, bound to a specific deployed contract.
+func NewITRC21Transactor(address common.Address, transactor bind.ContractTransactor) (*ITRC21Transactor, error) {
+ contract, err := bindITRC21(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21Transactor{contract: contract}, nil
+}
+
+// NewITRC21Filterer creates a new log filterer instance of ITRC21, bound to a specific deployed contract.
+func NewITRC21Filterer(address common.Address, filterer bind.ContractFilterer) (*ITRC21Filterer, error) {
+ contract, err := bindITRC21(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21Filterer{contract: contract}, nil
+}
+
+// bindITRC21 binds a generic wrapper to an already deployed contract.
+func bindITRC21(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(ITRC21ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ITRC21 *ITRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ITRC21.Contract.ITRC21Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ITRC21 *ITRC21Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ITRC21.Contract.ITRC21Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ITRC21 *ITRC21Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ITRC21.Contract.ITRC21Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ITRC21 *ITRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ITRC21.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ITRC21 *ITRC21TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ITRC21.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ITRC21 *ITRC21TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ITRC21.Contract.contract.Transact(opts, method, params...)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_ITRC21 *ITRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "allowance", owner, spender)
+ return *ret0, err
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_ITRC21 *ITRC21Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _ITRC21.Contract.Allowance(&_ITRC21.CallOpts, owner, spender)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_ITRC21 *ITRC21CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _ITRC21.Contract.Allowance(&_ITRC21.CallOpts, owner, spender)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(who address) constant returns(uint256)
+func (_ITRC21 *ITRC21Caller) BalanceOf(opts *bind.CallOpts, who common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "balanceOf", who)
+ return *ret0, err
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(who address) constant returns(uint256)
+func (_ITRC21 *ITRC21Session) BalanceOf(who common.Address) (*big.Int, error) {
+ return _ITRC21.Contract.BalanceOf(&_ITRC21.CallOpts, who)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(who address) constant returns(uint256)
+func (_ITRC21 *ITRC21CallerSession) BalanceOf(who common.Address) (*big.Int, error) {
+ return _ITRC21.Contract.BalanceOf(&_ITRC21.CallOpts, who)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_ITRC21 *ITRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) {
+ var (
+ ret0 = new(uint8)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "decimals")
+ return *ret0, err
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_ITRC21 *ITRC21Session) Decimals() (uint8, error) {
+ return _ITRC21.Contract.Decimals(&_ITRC21.CallOpts)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_ITRC21 *ITRC21CallerSession) Decimals() (uint8, error) {
+ return _ITRC21.Contract.Decimals(&_ITRC21.CallOpts)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_ITRC21 *ITRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "estimateFee", value)
+ return *ret0, err
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_ITRC21 *ITRC21Session) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _ITRC21.Contract.EstimateFee(&_ITRC21.CallOpts, value)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_ITRC21 *ITRC21CallerSession) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _ITRC21.Contract.EstimateFee(&_ITRC21.CallOpts, value)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_ITRC21 *ITRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "issuer")
+ return *ret0, err
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_ITRC21 *ITRC21Session) Issuer() (common.Address, error) {
+ return _ITRC21.Contract.Issuer(&_ITRC21.CallOpts)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_ITRC21 *ITRC21CallerSession) Issuer() (common.Address, error) {
+ return _ITRC21.Contract.Issuer(&_ITRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_ITRC21 *ITRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _ITRC21.contract.Call(opts, out, "totalSupply")
+ return *ret0, err
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_ITRC21 *ITRC21Session) TotalSupply() (*big.Int, error) {
+ return _ITRC21.Contract.TotalSupply(&_ITRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_ITRC21 *ITRC21CallerSession) TotalSupply() (*big.Int, error) {
+ return _ITRC21.Contract.TotalSupply(&_ITRC21.CallOpts)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Transactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.contract.Transact(opts, "approve", spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Session) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.Approve(&_ITRC21.TransactOpts, spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21TransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.Approve(&_ITRC21.TransactOpts, spender, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Transactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.contract.Transact(opts, "transfer", to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Session) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.Transfer(&_ITRC21.TransactOpts, to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21TransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.Transfer(&_ITRC21.TransactOpts, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.contract.Transact(opts, "transferFrom", from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21Session) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.TransferFrom(&_ITRC21.TransactOpts, from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_ITRC21 *ITRC21TransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _ITRC21.Contract.TransferFrom(&_ITRC21.TransactOpts, from, to, value)
+}
+
+// ITRC21ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ITRC21 contract.
+type ITRC21ApprovalIterator struct {
+ Event *ITRC21Approval // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ITRC21ApprovalIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ITRC21ApprovalIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ITRC21ApprovalIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ITRC21Approval represents a Approval event raised by the ITRC21 contract.
+type ITRC21Approval struct {
+ Owner common.Address
+ Spender common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ITRC21ApprovalIterator, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21ApprovalIterator{contract: _ITRC21.contract, event: "Approval", logs: logs, sub: sub}, nil
+}
+
+// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ITRC21Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ITRC21Approval)
+ if err := _ITRC21.contract.UnpackLog(event, "Approval", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ITRC21FeeIterator is returned from FilterFee and is used to iterate over the raw logs and unpacked data for Fee events raised by the ITRC21 contract.
+type ITRC21FeeIterator struct {
+ Event *ITRC21Fee // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ITRC21FeeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ITRC21FeeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ITRC21FeeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ITRC21Fee represents a Fee event raised by the ITRC21 contract.
+type ITRC21Fee struct {
+ From common.Address
+ To common.Address
+ Issuer common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterFee is a free log retrieval operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) FilterFee(opts *bind.FilterOpts, from []common.Address, to []common.Address, issuer []common.Address) (*ITRC21FeeIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.FilterLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21FeeIterator{contract: _ITRC21.contract, event: "Fee", logs: logs, sub: sub}, nil
+}
+
+// WatchFee is a free log subscription operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) WatchFee(opts *bind.WatchOpts, sink chan<- *ITRC21Fee, from []common.Address, to []common.Address, issuer []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.WatchLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ITRC21Fee)
+ if err := _ITRC21.contract.UnpackLog(event, "Fee", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ITRC21TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ITRC21 contract.
+type ITRC21TransferIterator struct {
+ Event *ITRC21Transfer // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ITRC21TransferIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ITRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ITRC21TransferIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ITRC21TransferIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ITRC21Transfer represents a Transfer event raised by the ITRC21 contract.
+type ITRC21Transfer struct {
+ From common.Address
+ To common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ITRC21TransferIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.FilterLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ITRC21TransferIterator{contract: _ITRC21.contract, event: "Transfer", logs: logs, sub: sub}, nil
+}
+
+// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_ITRC21 *ITRC21Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ITRC21Transfer, from []common.Address, to []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _ITRC21.contract.WatchLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ITRC21Transfer)
+ if err := _ITRC21.contract.UnpackLog(event, "Transfer", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21ABI is the input ABI used to generate the binding from.
+const MyTRC21ABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"estimateFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"issuer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"burnId\",\"type\":\"uint256\"}],\"name\":\"getBurn\",\"outputs\":[{\"name\":\"_burner\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setMinFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"depositFee\",\"type\":\"uint256\"}],\"name\":\"setDepositFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"pending\",\"type\":\"bool\"},{\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"burnList\",\"outputs\":[{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"burner\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"name\":\"destination\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"},{\"name\":\"executed\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"WITHDRAW_FEE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"from\",\"type\":\"uint256\"},{\"name\":\"to\",\"type\":\"uint256\"},{\"name\":\"pending\",\"type\":\"bool\"},{\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"withdrawFee\",\"type\":\"uint256\"}],\"name\":\"setWithdrawFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferContractIssuer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"destination\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"DEPOSIT_FEE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getBurnCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"burn\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_owners\",\"type\":\"address[]\"},{\"name\":\"_required\",\"type\":\"uint256\"},{\"name\":\"_name\",\"type\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\"},{\"name\":\"_decimals\",\"type\":\"uint8\"},{\"name\":\"cap\",\"type\":\"uint256\"},{\"name\":\"minFee\",\"type\":\"uint256\"},{\"name\":\"depositFee\",\"type\":\"uint256\"},{\"name\":\"withdrawFee\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"burnID\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"burner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TokenBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"}]"
+
+// MyTRC21Bin is the compiled bytecode used for deploying new contracts.
+const MyTRC21Bin = `0x6080604052600060085560006009553480156200001b57600080fd5b5060405162002a7b38038062002a7b8339810160409081528151602080840151928401516060850151608086015160a087015160c088015160e08901516101008a0151958a018051988b019a909895019693959294919390929160009189918991899162000090916005919086019062000356565b508151620000a690600690602085019062000356565b506007805460ff191660ff92909216919091179055505089518960328211801590620000d25750818111155b8015620000de57508015155b8015620000ea57508115155b1515620000f657600080fd5b6200010b338864010000000062000240810204565b6200011f33640100000000620002ff810204565b620001338664010000000062000337810204565b600092505b8b518310156200020b57600c60008d858151811015156200015557fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff16158015620001ab57508b838151811015156200019357fe5b90602001906020020151600160a060020a0316600014155b1515620001b757600080fd5b6001600c60008e86815181101515620001cc57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000138565b8b516200022090600d9060208f0190620003db565b505050600e98909855600991909155600855506200048895505050505050565b600160a060020a03821615156200025657600080fd5b6004546200027390826401000000006200221b6200033c82021704565b600455600160a060020a038216600090815260208190526040902054620002a990826401000000006200221b6200033c82021704565b600160a060020a0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600160a060020a03811615156200031557600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b600155565b6000828201838110156200034f57600080fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200039957805160ff1916838001178555620003c9565b82800160010185558215620003c9579182015b82811115620003c9578251825591602001919060010190620003ac565b50620003d792915062000441565b5090565b82805482825590600052602060002090810192821562000433579160200282015b82811115620004335782518254600160a060020a031916600160a060020a03909116178255602090920191600190910190620003fc565b50620003d792915062000461565b6200045e91905b80821115620003d7576000815560010162000448565b90565b6200045e91905b80821115620003d7578054600160a060020a031916815560010162000468565b6125e380620004986000396000f30060806040526004361061020e5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461021357806306fdde0314610247578063095ea7b3146102d1578063127e8e4d14610309578063173825d91461033357806318160ddd146103565780631d1438481461036b57806320ea8d861461038057806323b872dd1461039857806324ec7590146103c25780632eb3f49b146103d75780632f54bf6e14610487578063313ce567146104a857806331ac9920146104d35780633411c81c146104eb578063490ae2101461050f57806354741525146105275780637065cb481461054657806370a082311461056757806377661c6414610588578063784547a7146105fa5780638b51d13f1461061257806395d89b411461062a5780639ace38c21461063f5780639bff5ddb146106fa578063a0e67e2b1461070f578063a8abe69a14610774578063a9059cbb14610799578063b5dc40c3146107bd578063b6ac642a146107d5578063b77bf600146107ed578063ba51a6df14610802578063c01a8c841461081a578063c28ce6ff14610832578063c642747414610853578063d74f8edd146108bc578063dc8452cd146108d1578063dd62ed3e146108e6578063de363e651461090d578063e20056e614610922578063e7cf548c14610949578063ee22610b1461095e578063fe9d930314610976575b600080fd5b34801561021f57600080fd5b5061022b6004356109d4565b60408051600160a060020a039092168252519081900360200190f35b34801561025357600080fd5b5061025c6109fc565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029657818101518382015260200161027e565b50505050905090810190601f1680156102c35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102dd57600080fd5b506102f5600160a060020a0360043516602435610a93565b604080519115158252519081900360200190f35b34801561031557600080fd5b50610321600435610b4d565b60408051918252519081900360200190f35b34801561033f57600080fd5b50610354600160a060020a0360043516610b79565b005b34801561036257600080fd5b50610321610cf0565b34801561037757600080fd5b5061022b610cf6565b34801561038c57600080fd5b50610354600435610d05565b3480156103a457600080fd5b506102f5600160a060020a0360043581169060243516604435610dbf565b3480156103ce57600080fd5b50610321610f03565b3480156103e357600080fd5b506103ef600435610f09565b6040518084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561044a578181015183820152602001610432565b50505050905090810190601f1680156104775780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b34801561049357600080fd5b506102f5600160a060020a0360043516611016565b3480156104b457600080fd5b506104bd61102b565b6040805160ff9092168252519081900360200190f35b3480156104df57600080fd5b50610354600435611034565b3480156104f757600080fd5b506102f5600435600160a060020a0360243516611057565b34801561051b57600080fd5b50610354600435611077565b34801561053357600080fd5b5061032160043515156024351515611098565b34801561055257600080fd5b50610354600160a060020a0360043516611104565b34801561057357600080fd5b50610321600160a060020a0360043516611229565b34801561059457600080fd5b506105a0600435611244565b6040518084815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360008381101561044a578181015183820152602001610432565b34801561060657600080fd5b506102f560043561130d565b34801561061e57600080fd5b50610321600435611391565b34801561063657600080fd5b5061025c611400565b34801561064b57600080fd5b50610657600435611461565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156106bc5781810151838201526020016106a4565b50505050905090810190601f1680156106e95780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561070657600080fd5b50610321611520565b34801561071b57600080fd5b50610724611526565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610760578181015183820152602001610748565b505050509050019250505060405180910390f35b34801561078057600080fd5b5061072460043560243560443515156064351515611587565b3480156107a557600080fd5b506102f5600160a060020a03600435166024356116d3565b3480156107c957600080fd5b506107246004356117a5565b3480156107e157600080fd5b5061035460043561191e565b3480156107f957600080fd5b5061032161193f565b34801561080e57600080fd5b50610354600435611945565b34801561082657600080fd5b506103546004356119c4565b34801561083e57600080fd5b50610354600160a060020a0360043516611a8d565b34801561085f57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610321948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750611ac19650505050505050565b3480156108c857600080fd5b50610321611ae0565b3480156108dd57600080fd5b50610321611ae5565b3480156108f257600080fd5b50610321600160a060020a0360043581169060243516611aeb565b34801561091957600080fd5b50610321611b16565b34801561092e57600080fd5b50610354600160a060020a0360043581169060243516611b1c565b34801561095557600080fd5b50610321611ca6565b34801561096a57600080fd5b50610354600435611cac565b34801561098257600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610354958335953695604494919390910191908190840183828082843750949750611f079650505050505050565b600d8054829081106109e257fe5b600091825260209091200154600160a060020a0316905081565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a885780601f10610a5d57610100808354040283529160200191610a88565b820191906000526020600020905b815481529060010190602001808311610a6b57829003601f168201915b505050505090505b90565b6000600160a060020a0383161515610aaa57600080fd5b600154336000908152602081905260409020541015610ac857600080fd5b336000818152600360209081526040808320600160a060020a0388811685529252909120849055600254600154610b04939291909116906120fb565b604080518381529051600160a060020a0385169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a350600192915050565b600154600090610b7390610b67848463ffffffff6121ed16565b9063ffffffff61221b16565b92915050565b6000333014610b8757600080fd5b600160a060020a0382166000908152600c6020526040902054829060ff161515610bb057600080fd5b600160a060020a0383166000908152600c60205260408120805460ff1916905591505b600d5460001901821015610c8b5782600160a060020a0316600d83815481101515610bfa57fe5b600091825260209091200154600160a060020a03161415610c8057600d80546000198101908110610c2757fe5b600091825260209091200154600d8054600160a060020a039092169184908110610c4d57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550610c8b565b600190910190610bd3565b600d80546000190190610c9e90826124f6565b50600d54600e541115610cb757600d54610cb790611945565b604051600160a060020a038416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b60045490565b600254600160a060020a031690565b336000818152600c602052604090205460ff161515610d2357600080fd5b6000828152600b602090815260408083203380855292529091205483919060ff161515610d4f57600080fd5b6000848152600a6020526040902060030154849060ff1615610d7057600080fd5b6000858152600b60209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b600080610dd76001548461221b90919063ffffffff16565b600160a060020a038616600090815260208190526040902054909150811115610dff57600080fd5b600160a060020a0385166000908152600360209081526040808320338452909152902054831115610e2f57600080fd5b600160a060020a0385166000908152600360209081526040808320338452909152902054610e63908263ffffffff61222d16565b600160a060020a0386166000908152600360209081526040808320338452909152902055610e928585856120fb565b600254600154610eaf918791600160a060020a03909116906120fb565b6002546001546040805191825251600160a060020a039283169287169133917ffcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd999181900360200190a4506001949350505050565b60015490565b6000806060601084815481101515610f1d57fe5b600091825260209091206001600390920201015460108054600160a060020a0390921694509085908110610f4d57fe5b9060005260206000209060030201600001549150601084815481101515610f7057fe5b600091825260209182902060026003909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156110085780601f10610fdd57610100808354040283529160200191611008565b820191906000526020600020905b815481529060010190602001808311610feb57829003601f168201915b505050505090509193909250565b600c6020526000908152604090205460ff1681565b60075460ff1690565b600254600160a060020a0316331461104b57600080fd5b61105481612244565b50565b600b60209081526000928352604080842090915290825290205460ff1681565b61107f610cf6565b600160a060020a0316331461109357600080fd5b600955565b6000805b600f548110156110fd578380156110c557506000818152600a602052604090206003015460ff16155b806110e957508280156110e957506000818152600a602052604090206003015460ff165b156110f5576001820191505b60010161109c565b5092915050565b33301461111057600080fd5b600160a060020a0381166000908152600c6020526040902054819060ff161561113857600080fd5b81600160a060020a038116151561114e57600080fd5b600d80549050600101600e546032821115801561116b5750818111155b801561117657508015155b801561118157508115155b151561118c57600080fd5b600160a060020a0385166000818152600c6020526040808220805460ff19166001908117909155600d8054918201815583527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb501805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600160a060020a031660009081526020819052604090205490565b601080548290811061125257fe5b6000918252602091829020600391909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f8101889004880285018801909252818452939650600160a060020a03909116949192918301828280156113035780601f106112d857610100808354040283529160200191611303565b820191906000526020600020905b8154815290600101906020018083116112e657829003601f168201915b5050505050905083565b600080805b600d5481101561138a576000848152600b60205260408120600d80549192918490811061133b57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561136f576001820191505b600e54821415611382576001925061138a565b600101611312565b5050919050565b6000805b600d548110156113fa576000838152600b60205260408120600d8054919291849081106113be57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff16156113f2576001820191505b600101611395565b50919050565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a885780601f10610a5d57610100808354040283529160200191610a88565b600a6020908152600091825260409182902080546001808301546002808501805488516101009582161595909502600019011691909104601f8101879004870284018701909752868352600160a060020a0390931695909491929183018282801561150d5780601f106114e25761010080835404028352916020019161150d565b820191906000526020600020905b8154815290600101906020018083116114f057829003601f168201915b5050506003909301549192505060ff1684565b60085481565b6060600d805480602002602001604051908101604052809291908181526020018280548015610a8857602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611560575050505050905090565b606060006060600080600f54881161159f57876115a3565b600f545b93508884036040519080825280602002602001820160405280156115d1578160200160208202803883390190505b509250600091508890505b878110156116555786801561160357506000818152600a602052604090206003015460ff16155b80611627575085801561162757506000818152600a602052604090206003015460ff165b1561164d5780838381518110151561163b57fe5b60209081029091010152600191909101905b6001016115dc565b8160405190808252806020026020018201604052801561167f578160200160208202803883390190505b509450600090505b818110156116c757828181518110151561169d57fe5b9060200190602002015185828151811015156116b557fe5b60209081029091010152600101611687565b50505050949350505050565b600080600160a060020a03841615156116eb57600080fd5b6001546116ff90849063ffffffff61221b16565b3360009081526020819052604090205490915081111561171e57600080fd5b6117293385856120fb565b6000600154111561179b57600254600154611751913391600160a060020a03909116906120fb565b6002546001546040805191825251600160a060020a039283169287169133917ffcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd999181900360200190a45b5060019392505050565b606080600080600d805490506040519080825280602002602001820160405280156117da578160200160208202803883390190505b50925060009150600090505b600d54811015611897576000858152600b60205260408120600d80549192918490811061180f57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561188f57600d80548290811061184a57fe5b6000918252602090912001548351600160a060020a039091169084908490811061187057fe5b600160a060020a03909216602092830290910190910152600191909101905b6001016117e6565b816040519080825280602002602001820160405280156118c1578160200160208202803883390190505b509350600090505b818110156119165782818151811015156118df57fe5b9060200190602002015184828151811015156118f757fe5b600160a060020a039092166020928302909101909101526001016118c9565b505050919050565b611926610cf6565b600160a060020a0316331461193a57600080fd5b600855565b600f5481565b33301461195157600080fd5b600d5481603282118015906119665750818111155b801561197157508015155b801561197c57508115155b151561198757600080fd5b600e8390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b336000818152600c602052604090205460ff1615156119e257600080fd5b6000828152600a60205260409020548290600160a060020a03161515611a0757600080fd5b6000838152600b602090815260408083203380855292529091205484919060ff1615611a3257600080fd5b6000858152600b60209081526040808320338085529252808320805460ff191660011790555187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3611a8685611cac565b5050505050565b611a95610cf6565b600160a060020a03163314611aa957600080fd5b600160a060020a038116156110545761105433612249565b6000611ace84848461228d565b9050611ad9816119c4565b9392505050565b603281565b600e5481565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b60095481565b6000333014611b2a57600080fd5b600160a060020a0383166000908152600c6020526040902054839060ff161515611b5357600080fd5b600160a060020a0383166000908152600c6020526040902054839060ff1615611b7b57600080fd5b600092505b600d54831015611c0c5784600160a060020a0316600d84815481101515611ba357fe5b600091825260209091200154600160a060020a03161415611c015783600d84815481101515611bce57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550611c0c565b600190920191611b80565b600160a060020a038086166000818152600c6020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b60105490565b336000818152600c602052604081205490919060ff161515611ccd57600080fd5b6000838152600b602090815260408083203380855292529091205484919060ff161515611cf957600080fd5b6000858152600a6020526040902060030154859060ff1615611d1a57600080fd5b611d238661130d565b15611eff576000868152600a6020526040902060038101805460ff19166001908117909155600280830154929750600019918316156101000291909101909116041515611ded576009546001860154611d819163ffffffff61222d16565b600186018190558554611d9f91600160a060020a039091169061237e565b60006009541115611dbd57611dbd611db5610cf6565b60095461237e565b60405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2611eff565b8460000160009054906101000a9004600160a060020a0316600160a060020a03168560010154866002016040518082805460018160011615610100020316600290048015611e7c5780601f10611e5157610100808354040283529160200191611e7c565b820191906000526020600020905b815481529060010190602001808311611e5f57829003601f168201915b505091505060006040518083038185875af19250505015611ec75760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a2611eff565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038501805460ff191690555b505050505050565b6008546000908311611f1857600080fd5b611f223384612428565b60006008541115611f4057611f40611f38610cf6565b60085461237e565b600854611f5490849063ffffffff61222d16565b604080516060810182528281523360208083019182529282018681526010805460018101808355600092909252845160039091027f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672810191825593517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67385018054600160a060020a039290921673ffffffffffffffffffffffffffffffffffffffff199092169190911790559151805196975090959394919361203e937f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6740192919091019061251f565b5050505033600160a060020a03166001601080549050037f6905852b196f81e7e03058512a599446c358027fc943c1e193b6649a39379bb583856040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156120bb5781810151838201526020016120a3565b50505050905090810190601f1680156120e85780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3505050565b600160a060020a03831660009081526020819052604090205481111561212057600080fd5b600160a060020a038216151561213557600080fd5b600160a060020a03831660009081526020819052604090205461215e908263ffffffff61222d16565b600160a060020a038085166000908152602081905260408082209390935590841681522054612193908263ffffffff61221b16565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008083151561220057600091506110fd565b5082820282848281151561221057fe5b0414611ad957600080fd5b600082820183811015611ad957600080fd5b6000808383111561223d57600080fd5b5050900390565b600155565b600160a060020a038116151561225e57600080fd5b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600083600160a060020a03811615156122a557600080fd5b600f5460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152600a8452959095208451815473ffffffffffffffffffffffffffffffffffffffff19169416939093178355516001830155925180519496509193909261232692600285019291019061251f565b50606091909101516003909101805460ff1916911515919091179055600f8054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b600160a060020a038216151561239357600080fd5b6004546123a6908263ffffffff61221b16565b600455600160a060020a0382166000908152602081905260409020546123d2908263ffffffff61221b16565b600160a060020a0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600160a060020a038216151561243d57600080fd5b600160a060020a03821660009081526020819052604090205481111561246257600080fd5b600454612475908263ffffffff61222d16565b600455600160a060020a0382166000908152602081905260409020546124a1908263ffffffff61222d16565b600160a060020a038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b81548183558181111561251a5760008381526020902061251a91810190830161259d565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061256057805160ff191683800117855561258d565b8280016001018555821561258d579182015b8281111561258d578251825591602001919060010190612572565b5061259992915061259d565b5090565b610a9091905b8082111561259957600081556001016125a35600a165627a7a72305820bffa6044329c4005991204d5fa011824a3408b8d46a641ee00f98556e9536c350029`
+
+// DeployMyTRC21 deploys a new Ethereum contract, binding an instance of MyTRC21 to it.
+func DeployMyTRC21(auth *bind.TransactOpts, backend bind.ContractBackend, _owners []common.Address, _required *big.Int, _name string, _symbol string, _decimals uint8, cap *big.Int, minFee *big.Int, depositFee *big.Int, withdrawFee *big.Int) (common.Address, *types.Transaction, *MyTRC21, error) {
+ parsed, err := abi.JSON(strings.NewReader(MyTRC21ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(MyTRC21Bin), backend, _owners, _required, _name, _symbol, _decimals, cap, minFee, depositFee, withdrawFee)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &MyTRC21{MyTRC21Caller: MyTRC21Caller{contract: contract}, MyTRC21Transactor: MyTRC21Transactor{contract: contract}, MyTRC21Filterer: MyTRC21Filterer{contract: contract}}, nil
+}
+
+// MyTRC21 is an auto generated Go binding around an Ethereum contract.
+type MyTRC21 struct {
+ MyTRC21Caller // Read-only binding to the contract
+ MyTRC21Transactor // Write-only binding to the contract
+ MyTRC21Filterer // Log filterer for contract events
+}
+
+// MyTRC21Caller is an auto generated read-only Go binding around an Ethereum contract.
+type MyTRC21Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// MyTRC21Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type MyTRC21Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// MyTRC21Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type MyTRC21Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// MyTRC21Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type MyTRC21Session struct {
+ Contract *MyTRC21 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// MyTRC21CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type MyTRC21CallerSession struct {
+ Contract *MyTRC21Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// MyTRC21TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type MyTRC21TransactorSession struct {
+ Contract *MyTRC21Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// MyTRC21Raw is an auto generated low-level Go binding around an Ethereum contract.
+type MyTRC21Raw struct {
+ Contract *MyTRC21 // Generic contract binding to access the raw methods on
+}
+
+// MyTRC21CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type MyTRC21CallerRaw struct {
+ Contract *MyTRC21Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// MyTRC21TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type MyTRC21TransactorRaw struct {
+ Contract *MyTRC21Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewMyTRC21 creates a new instance of MyTRC21, bound to a specific deployed contract.
+func NewMyTRC21(address common.Address, backend bind.ContractBackend) (*MyTRC21, error) {
+ contract, err := bindMyTRC21(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21{MyTRC21Caller: MyTRC21Caller{contract: contract}, MyTRC21Transactor: MyTRC21Transactor{contract: contract}, MyTRC21Filterer: MyTRC21Filterer{contract: contract}}, nil
+}
+
+// NewMyTRC21Caller creates a new read-only instance of MyTRC21, bound to a specific deployed contract.
+func NewMyTRC21Caller(address common.Address, caller bind.ContractCaller) (*MyTRC21Caller, error) {
+ contract, err := bindMyTRC21(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21Caller{contract: contract}, nil
+}
+
+// NewMyTRC21Transactor creates a new write-only instance of MyTRC21, bound to a specific deployed contract.
+func NewMyTRC21Transactor(address common.Address, transactor bind.ContractTransactor) (*MyTRC21Transactor, error) {
+ contract, err := bindMyTRC21(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21Transactor{contract: contract}, nil
+}
+
+// NewMyTRC21Filterer creates a new log filterer instance of MyTRC21, bound to a specific deployed contract.
+func NewMyTRC21Filterer(address common.Address, filterer bind.ContractFilterer) (*MyTRC21Filterer, error) {
+ contract, err := bindMyTRC21(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21Filterer{contract: contract}, nil
+}
+
+// bindMyTRC21 binds a generic wrapper to an already deployed contract.
+func bindMyTRC21(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(MyTRC21ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_MyTRC21 *MyTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _MyTRC21.Contract.MyTRC21Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_MyTRC21 *MyTRC21Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _MyTRC21.Contract.MyTRC21Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_MyTRC21 *MyTRC21Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _MyTRC21.Contract.MyTRC21Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_MyTRC21 *MyTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _MyTRC21.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_MyTRC21 *MyTRC21TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _MyTRC21.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_MyTRC21 *MyTRC21TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _MyTRC21.Contract.contract.Transact(opts, method, params...)
+}
+
+// DEPOSITFEE is a free data retrieval call binding the contract method 0xde363e65.
+//
+// Solidity: function DEPOSIT_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) DEPOSITFEE(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "DEPOSIT_FEE")
+ return *ret0, err
+}
+
+// DEPOSITFEE is a free data retrieval call binding the contract method 0xde363e65.
+//
+// Solidity: function DEPOSIT_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) DEPOSITFEE() (*big.Int, error) {
+ return _MyTRC21.Contract.DEPOSITFEE(&_MyTRC21.CallOpts)
+}
+
+// DEPOSITFEE is a free data retrieval call binding the contract method 0xde363e65.
+//
+// Solidity: function DEPOSIT_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) DEPOSITFEE() (*big.Int, error) {
+ return _MyTRC21.Contract.DEPOSITFEE(&_MyTRC21.CallOpts)
+}
+
+// MAXOWNERCOUNT is a free data retrieval call binding the contract method 0xd74f8edd.
+//
+// Solidity: function MAX_OWNER_COUNT() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) MAXOWNERCOUNT(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "MAX_OWNER_COUNT")
+ return *ret0, err
+}
+
+// MAXOWNERCOUNT is a free data retrieval call binding the contract method 0xd74f8edd.
+//
+// Solidity: function MAX_OWNER_COUNT() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) MAXOWNERCOUNT() (*big.Int, error) {
+ return _MyTRC21.Contract.MAXOWNERCOUNT(&_MyTRC21.CallOpts)
+}
+
+// MAXOWNERCOUNT is a free data retrieval call binding the contract method 0xd74f8edd.
+//
+// Solidity: function MAX_OWNER_COUNT() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) MAXOWNERCOUNT() (*big.Int, error) {
+ return _MyTRC21.Contract.MAXOWNERCOUNT(&_MyTRC21.CallOpts)
+}
+
+// WITHDRAWFEE is a free data retrieval call binding the contract method 0x9bff5ddb.
+//
+// Solidity: function WITHDRAW_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) WITHDRAWFEE(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "WITHDRAW_FEE")
+ return *ret0, err
+}
+
+// WITHDRAWFEE is a free data retrieval call binding the contract method 0x9bff5ddb.
+//
+// Solidity: function WITHDRAW_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) WITHDRAWFEE() (*big.Int, error) {
+ return _MyTRC21.Contract.WITHDRAWFEE(&_MyTRC21.CallOpts)
+}
+
+// WITHDRAWFEE is a free data retrieval call binding the contract method 0x9bff5ddb.
+//
+// Solidity: function WITHDRAW_FEE() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) WITHDRAWFEE() (*big.Int, error) {
+ return _MyTRC21.Contract.WITHDRAWFEE(&_MyTRC21.CallOpts)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "allowance", owner, spender)
+ return *ret0, err
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _MyTRC21.Contract.Allowance(&_MyTRC21.CallOpts, owner, spender)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _MyTRC21.Contract.Allowance(&_MyTRC21.CallOpts, owner, spender)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "balanceOf", owner)
+ return *ret0, err
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) BalanceOf(owner common.Address) (*big.Int, error) {
+ return _MyTRC21.Contract.BalanceOf(&_MyTRC21.CallOpts, owner)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) BalanceOf(owner common.Address) (*big.Int, error) {
+ return _MyTRC21.Contract.BalanceOf(&_MyTRC21.CallOpts, owner)
+}
+
+// BurnList is a free data retrieval call binding the contract method 0x77661c64.
+//
+// Solidity: function burnList( uint256) constant returns(value uint256, burner address, data bytes)
+func (_MyTRC21 *MyTRC21Caller) BurnList(opts *bind.CallOpts, arg0 *big.Int) (struct {
+ Value *big.Int
+ Burner common.Address
+ Data []byte
+}, error) {
+ ret := new(struct {
+ Value *big.Int
+ Burner common.Address
+ Data []byte
+ })
+ out := ret
+ err := _MyTRC21.contract.Call(opts, out, "burnList", arg0)
+ return *ret, err
+}
+
+// BurnList is a free data retrieval call binding the contract method 0x77661c64.
+//
+// Solidity: function burnList( uint256) constant returns(value uint256, burner address, data bytes)
+func (_MyTRC21 *MyTRC21Session) BurnList(arg0 *big.Int) (struct {
+ Value *big.Int
+ Burner common.Address
+ Data []byte
+}, error) {
+ return _MyTRC21.Contract.BurnList(&_MyTRC21.CallOpts, arg0)
+}
+
+// BurnList is a free data retrieval call binding the contract method 0x77661c64.
+//
+// Solidity: function burnList( uint256) constant returns(value uint256, burner address, data bytes)
+func (_MyTRC21 *MyTRC21CallerSession) BurnList(arg0 *big.Int) (struct {
+ Value *big.Int
+ Burner common.Address
+ Data []byte
+}, error) {
+ return _MyTRC21.Contract.BurnList(&_MyTRC21.CallOpts, arg0)
+}
+
+// Confirmations is a free data retrieval call binding the contract method 0x3411c81c.
+//
+// Solidity: function confirmations( uint256, address) constant returns(bool)
+func (_MyTRC21 *MyTRC21Caller) Confirmations(opts *bind.CallOpts, arg0 *big.Int, arg1 common.Address) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "confirmations", arg0, arg1)
+ return *ret0, err
+}
+
+// Confirmations is a free data retrieval call binding the contract method 0x3411c81c.
+//
+// Solidity: function confirmations( uint256, address) constant returns(bool)
+func (_MyTRC21 *MyTRC21Session) Confirmations(arg0 *big.Int, arg1 common.Address) (bool, error) {
+ return _MyTRC21.Contract.Confirmations(&_MyTRC21.CallOpts, arg0, arg1)
+}
+
+// Confirmations is a free data retrieval call binding the contract method 0x3411c81c.
+//
+// Solidity: function confirmations( uint256, address) constant returns(bool)
+func (_MyTRC21 *MyTRC21CallerSession) Confirmations(arg0 *big.Int, arg1 common.Address) (bool, error) {
+ return _MyTRC21.Contract.Confirmations(&_MyTRC21.CallOpts, arg0, arg1)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_MyTRC21 *MyTRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) {
+ var (
+ ret0 = new(uint8)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "decimals")
+ return *ret0, err
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_MyTRC21 *MyTRC21Session) Decimals() (uint8, error) {
+ return _MyTRC21.Contract.Decimals(&_MyTRC21.CallOpts)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_MyTRC21 *MyTRC21CallerSession) Decimals() (uint8, error) {
+ return _MyTRC21.Contract.Decimals(&_MyTRC21.CallOpts)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "estimateFee", value)
+ return *ret0, err
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _MyTRC21.Contract.EstimateFee(&_MyTRC21.CallOpts, value)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _MyTRC21.Contract.EstimateFee(&_MyTRC21.CallOpts, value)
+}
+
+// GetBurn is a free data retrieval call binding the contract method 0x2eb3f49b.
+//
+// Solidity: function getBurn(burnId uint256) constant returns(_burner address, _value uint256, _data bytes)
+func (_MyTRC21 *MyTRC21Caller) GetBurn(opts *bind.CallOpts, burnId *big.Int) (struct {
+ Burner common.Address
+ Value *big.Int
+ Data []byte
+}, error) {
+ ret := new(struct {
+ Burner common.Address
+ Value *big.Int
+ Data []byte
+ })
+ out := ret
+ err := _MyTRC21.contract.Call(opts, out, "getBurn", burnId)
+ return *ret, err
+}
+
+// GetBurn is a free data retrieval call binding the contract method 0x2eb3f49b.
+//
+// Solidity: function getBurn(burnId uint256) constant returns(_burner address, _value uint256, _data bytes)
+func (_MyTRC21 *MyTRC21Session) GetBurn(burnId *big.Int) (struct {
+ Burner common.Address
+ Value *big.Int
+ Data []byte
+}, error) {
+ return _MyTRC21.Contract.GetBurn(&_MyTRC21.CallOpts, burnId)
+}
+
+// GetBurn is a free data retrieval call binding the contract method 0x2eb3f49b.
+//
+// Solidity: function getBurn(burnId uint256) constant returns(_burner address, _value uint256, _data bytes)
+func (_MyTRC21 *MyTRC21CallerSession) GetBurn(burnId *big.Int) (struct {
+ Burner common.Address
+ Value *big.Int
+ Data []byte
+}, error) {
+ return _MyTRC21.Contract.GetBurn(&_MyTRC21.CallOpts, burnId)
+}
+
+// GetBurnCount is a free data retrieval call binding the contract method 0xe7cf548c.
+//
+// Solidity: function getBurnCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) GetBurnCount(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getBurnCount")
+ return *ret0, err
+}
+
+// GetBurnCount is a free data retrieval call binding the contract method 0xe7cf548c.
+//
+// Solidity: function getBurnCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) GetBurnCount() (*big.Int, error) {
+ return _MyTRC21.Contract.GetBurnCount(&_MyTRC21.CallOpts)
+}
+
+// GetBurnCount is a free data retrieval call binding the contract method 0xe7cf548c.
+//
+// Solidity: function getBurnCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) GetBurnCount() (*big.Int, error) {
+ return _MyTRC21.Contract.GetBurnCount(&_MyTRC21.CallOpts)
+}
+
+// GetConfirmationCount is a free data retrieval call binding the contract method 0x8b51d13f.
+//
+// Solidity: function getConfirmationCount(transactionId uint256) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21Caller) GetConfirmationCount(opts *bind.CallOpts, transactionId *big.Int) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getConfirmationCount", transactionId)
+ return *ret0, err
+}
+
+// GetConfirmationCount is a free data retrieval call binding the contract method 0x8b51d13f.
+//
+// Solidity: function getConfirmationCount(transactionId uint256) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21Session) GetConfirmationCount(transactionId *big.Int) (*big.Int, error) {
+ return _MyTRC21.Contract.GetConfirmationCount(&_MyTRC21.CallOpts, transactionId)
+}
+
+// GetConfirmationCount is a free data retrieval call binding the contract method 0x8b51d13f.
+//
+// Solidity: function getConfirmationCount(transactionId uint256) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21CallerSession) GetConfirmationCount(transactionId *big.Int) (*big.Int, error) {
+ return _MyTRC21.Contract.GetConfirmationCount(&_MyTRC21.CallOpts, transactionId)
+}
+
+// GetConfirmations is a free data retrieval call binding the contract method 0xb5dc40c3.
+//
+// Solidity: function getConfirmations(transactionId uint256) constant returns(_confirmations address[])
+func (_MyTRC21 *MyTRC21Caller) GetConfirmations(opts *bind.CallOpts, transactionId *big.Int) ([]common.Address, error) {
+ var (
+ ret0 = new([]common.Address)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getConfirmations", transactionId)
+ return *ret0, err
+}
+
+// GetConfirmations is a free data retrieval call binding the contract method 0xb5dc40c3.
+//
+// Solidity: function getConfirmations(transactionId uint256) constant returns(_confirmations address[])
+func (_MyTRC21 *MyTRC21Session) GetConfirmations(transactionId *big.Int) ([]common.Address, error) {
+ return _MyTRC21.Contract.GetConfirmations(&_MyTRC21.CallOpts, transactionId)
+}
+
+// GetConfirmations is a free data retrieval call binding the contract method 0xb5dc40c3.
+//
+// Solidity: function getConfirmations(transactionId uint256) constant returns(_confirmations address[])
+func (_MyTRC21 *MyTRC21CallerSession) GetConfirmations(transactionId *big.Int) ([]common.Address, error) {
+ return _MyTRC21.Contract.GetConfirmations(&_MyTRC21.CallOpts, transactionId)
+}
+
+// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b.
+//
+// Solidity: function getOwners() constant returns(address[])
+func (_MyTRC21 *MyTRC21Caller) GetOwners(opts *bind.CallOpts) ([]common.Address, error) {
+ var (
+ ret0 = new([]common.Address)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getOwners")
+ return *ret0, err
+}
+
+// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b.
+//
+// Solidity: function getOwners() constant returns(address[])
+func (_MyTRC21 *MyTRC21Session) GetOwners() ([]common.Address, error) {
+ return _MyTRC21.Contract.GetOwners(&_MyTRC21.CallOpts)
+}
+
+// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b.
+//
+// Solidity: function getOwners() constant returns(address[])
+func (_MyTRC21 *MyTRC21CallerSession) GetOwners() ([]common.Address, error) {
+ return _MyTRC21.Contract.GetOwners(&_MyTRC21.CallOpts)
+}
+
+// GetTransactionCount is a free data retrieval call binding the contract method 0x54741525.
+//
+// Solidity: function getTransactionCount(pending bool, executed bool) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21Caller) GetTransactionCount(opts *bind.CallOpts, pending bool, executed bool) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getTransactionCount", pending, executed)
+ return *ret0, err
+}
+
+// GetTransactionCount is a free data retrieval call binding the contract method 0x54741525.
+//
+// Solidity: function getTransactionCount(pending bool, executed bool) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21Session) GetTransactionCount(pending bool, executed bool) (*big.Int, error) {
+ return _MyTRC21.Contract.GetTransactionCount(&_MyTRC21.CallOpts, pending, executed)
+}
+
+// GetTransactionCount is a free data retrieval call binding the contract method 0x54741525.
+//
+// Solidity: function getTransactionCount(pending bool, executed bool) constant returns(count uint256)
+func (_MyTRC21 *MyTRC21CallerSession) GetTransactionCount(pending bool, executed bool) (*big.Int, error) {
+ return _MyTRC21.Contract.GetTransactionCount(&_MyTRC21.CallOpts, pending, executed)
+}
+
+// GetTransactionIds is a free data retrieval call binding the contract method 0xa8abe69a.
+//
+// Solidity: function getTransactionIds(from uint256, to uint256, pending bool, executed bool) constant returns(_transactionIds uint256[])
+func (_MyTRC21 *MyTRC21Caller) GetTransactionIds(opts *bind.CallOpts, from *big.Int, to *big.Int, pending bool, executed bool) ([]*big.Int, error) {
+ var (
+ ret0 = new([]*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "getTransactionIds", from, to, pending, executed)
+ return *ret0, err
+}
+
+// GetTransactionIds is a free data retrieval call binding the contract method 0xa8abe69a.
+//
+// Solidity: function getTransactionIds(from uint256, to uint256, pending bool, executed bool) constant returns(_transactionIds uint256[])
+func (_MyTRC21 *MyTRC21Session) GetTransactionIds(from *big.Int, to *big.Int, pending bool, executed bool) ([]*big.Int, error) {
+ return _MyTRC21.Contract.GetTransactionIds(&_MyTRC21.CallOpts, from, to, pending, executed)
+}
+
+// GetTransactionIds is a free data retrieval call binding the contract method 0xa8abe69a.
+//
+// Solidity: function getTransactionIds(from uint256, to uint256, pending bool, executed bool) constant returns(_transactionIds uint256[])
+func (_MyTRC21 *MyTRC21CallerSession) GetTransactionIds(from *big.Int, to *big.Int, pending bool, executed bool) ([]*big.Int, error) {
+ return _MyTRC21.Contract.GetTransactionIds(&_MyTRC21.CallOpts, from, to, pending, executed)
+}
+
+// IsConfirmed is a free data retrieval call binding the contract method 0x784547a7.
+//
+// Solidity: function isConfirmed(transactionId uint256) constant returns(bool)
+func (_MyTRC21 *MyTRC21Caller) IsConfirmed(opts *bind.CallOpts, transactionId *big.Int) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "isConfirmed", transactionId)
+ return *ret0, err
+}
+
+// IsConfirmed is a free data retrieval call binding the contract method 0x784547a7.
+//
+// Solidity: function isConfirmed(transactionId uint256) constant returns(bool)
+func (_MyTRC21 *MyTRC21Session) IsConfirmed(transactionId *big.Int) (bool, error) {
+ return _MyTRC21.Contract.IsConfirmed(&_MyTRC21.CallOpts, transactionId)
+}
+
+// IsConfirmed is a free data retrieval call binding the contract method 0x784547a7.
+//
+// Solidity: function isConfirmed(transactionId uint256) constant returns(bool)
+func (_MyTRC21 *MyTRC21CallerSession) IsConfirmed(transactionId *big.Int) (bool, error) {
+ return _MyTRC21.Contract.IsConfirmed(&_MyTRC21.CallOpts, transactionId)
+}
+
+// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e.
+//
+// Solidity: function isOwner( address) constant returns(bool)
+func (_MyTRC21 *MyTRC21Caller) IsOwner(opts *bind.CallOpts, arg0 common.Address) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "isOwner", arg0)
+ return *ret0, err
+}
+
+// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e.
+//
+// Solidity: function isOwner( address) constant returns(bool)
+func (_MyTRC21 *MyTRC21Session) IsOwner(arg0 common.Address) (bool, error) {
+ return _MyTRC21.Contract.IsOwner(&_MyTRC21.CallOpts, arg0)
+}
+
+// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e.
+//
+// Solidity: function isOwner( address) constant returns(bool)
+func (_MyTRC21 *MyTRC21CallerSession) IsOwner(arg0 common.Address) (bool, error) {
+ return _MyTRC21.Contract.IsOwner(&_MyTRC21.CallOpts, arg0)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_MyTRC21 *MyTRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "issuer")
+ return *ret0, err
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_MyTRC21 *MyTRC21Session) Issuer() (common.Address, error) {
+ return _MyTRC21.Contract.Issuer(&_MyTRC21.CallOpts)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_MyTRC21 *MyTRC21CallerSession) Issuer() (common.Address, error) {
+ return _MyTRC21.Contract.Issuer(&_MyTRC21.CallOpts)
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "minFee")
+ return *ret0, err
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) MinFee() (*big.Int, error) {
+ return _MyTRC21.Contract.MinFee(&_MyTRC21.CallOpts)
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) MinFee() (*big.Int, error) {
+ return _MyTRC21.Contract.MinFee(&_MyTRC21.CallOpts)
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_MyTRC21 *MyTRC21Caller) Name(opts *bind.CallOpts) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "name")
+ return *ret0, err
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_MyTRC21 *MyTRC21Session) Name() (string, error) {
+ return _MyTRC21.Contract.Name(&_MyTRC21.CallOpts)
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_MyTRC21 *MyTRC21CallerSession) Name() (string, error) {
+ return _MyTRC21.Contract.Name(&_MyTRC21.CallOpts)
+}
+
+// Owners is a free data retrieval call binding the contract method 0x025e7c27.
+//
+// Solidity: function owners( uint256) constant returns(address)
+func (_MyTRC21 *MyTRC21Caller) Owners(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "owners", arg0)
+ return *ret0, err
+}
+
+// Owners is a free data retrieval call binding the contract method 0x025e7c27.
+//
+// Solidity: function owners( uint256) constant returns(address)
+func (_MyTRC21 *MyTRC21Session) Owners(arg0 *big.Int) (common.Address, error) {
+ return _MyTRC21.Contract.Owners(&_MyTRC21.CallOpts, arg0)
+}
+
+// Owners is a free data retrieval call binding the contract method 0x025e7c27.
+//
+// Solidity: function owners( uint256) constant returns(address)
+func (_MyTRC21 *MyTRC21CallerSession) Owners(arg0 *big.Int) (common.Address, error) {
+ return _MyTRC21.Contract.Owners(&_MyTRC21.CallOpts, arg0)
+}
+
+// Required is a free data retrieval call binding the contract method 0xdc8452cd.
+//
+// Solidity: function required() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) Required(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "required")
+ return *ret0, err
+}
+
+// Required is a free data retrieval call binding the contract method 0xdc8452cd.
+//
+// Solidity: function required() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) Required() (*big.Int, error) {
+ return _MyTRC21.Contract.Required(&_MyTRC21.CallOpts)
+}
+
+// Required is a free data retrieval call binding the contract method 0xdc8452cd.
+//
+// Solidity: function required() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) Required() (*big.Int, error) {
+ return _MyTRC21.Contract.Required(&_MyTRC21.CallOpts)
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_MyTRC21 *MyTRC21Caller) Symbol(opts *bind.CallOpts) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "symbol")
+ return *ret0, err
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_MyTRC21 *MyTRC21Session) Symbol() (string, error) {
+ return _MyTRC21.Contract.Symbol(&_MyTRC21.CallOpts)
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_MyTRC21 *MyTRC21CallerSession) Symbol() (string, error) {
+ return _MyTRC21.Contract.Symbol(&_MyTRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "totalSupply")
+ return *ret0, err
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) TotalSupply() (*big.Int, error) {
+ return _MyTRC21.Contract.TotalSupply(&_MyTRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) TotalSupply() (*big.Int, error) {
+ return _MyTRC21.Contract.TotalSupply(&_MyTRC21.CallOpts)
+}
+
+// TransactionCount is a free data retrieval call binding the contract method 0xb77bf600.
+//
+// Solidity: function transactionCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Caller) TransactionCount(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _MyTRC21.contract.Call(opts, out, "transactionCount")
+ return *ret0, err
+}
+
+// TransactionCount is a free data retrieval call binding the contract method 0xb77bf600.
+//
+// Solidity: function transactionCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21Session) TransactionCount() (*big.Int, error) {
+ return _MyTRC21.Contract.TransactionCount(&_MyTRC21.CallOpts)
+}
+
+// TransactionCount is a free data retrieval call binding the contract method 0xb77bf600.
+//
+// Solidity: function transactionCount() constant returns(uint256)
+func (_MyTRC21 *MyTRC21CallerSession) TransactionCount() (*big.Int, error) {
+ return _MyTRC21.Contract.TransactionCount(&_MyTRC21.CallOpts)
+}
+
+// Transactions is a free data retrieval call binding the contract method 0x9ace38c2.
+//
+// Solidity: function transactions( uint256) constant returns(destination address, value uint256, data bytes, executed bool)
+func (_MyTRC21 *MyTRC21Caller) Transactions(opts *bind.CallOpts, arg0 *big.Int) (struct {
+ Destination common.Address
+ Value *big.Int
+ Data []byte
+ Executed bool
+}, error) {
+ ret := new(struct {
+ Destination common.Address
+ Value *big.Int
+ Data []byte
+ Executed bool
+ })
+ out := ret
+ err := _MyTRC21.contract.Call(opts, out, "transactions", arg0)
+ return *ret, err
+}
+
+// Transactions is a free data retrieval call binding the contract method 0x9ace38c2.
+//
+// Solidity: function transactions( uint256) constant returns(destination address, value uint256, data bytes, executed bool)
+func (_MyTRC21 *MyTRC21Session) Transactions(arg0 *big.Int) (struct {
+ Destination common.Address
+ Value *big.Int
+ Data []byte
+ Executed bool
+}, error) {
+ return _MyTRC21.Contract.Transactions(&_MyTRC21.CallOpts, arg0)
+}
+
+// Transactions is a free data retrieval call binding the contract method 0x9ace38c2.
+//
+// Solidity: function transactions( uint256) constant returns(destination address, value uint256, data bytes, executed bool)
+func (_MyTRC21 *MyTRC21CallerSession) Transactions(arg0 *big.Int) (struct {
+ Destination common.Address
+ Value *big.Int
+ Data []byte
+ Executed bool
+}, error) {
+ return _MyTRC21.Contract.Transactions(&_MyTRC21.CallOpts, arg0)
+}
+
+// AddOwner is a paid mutator transaction binding the contract method 0x7065cb48.
+//
+// Solidity: function addOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21Transactor) AddOwner(opts *bind.TransactOpts, owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "addOwner", owner)
+}
+
+// AddOwner is a paid mutator transaction binding the contract method 0x7065cb48.
+//
+// Solidity: function addOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21Session) AddOwner(owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.AddOwner(&_MyTRC21.TransactOpts, owner)
+}
+
+// AddOwner is a paid mutator transaction binding the contract method 0x7065cb48.
+//
+// Solidity: function addOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) AddOwner(owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.AddOwner(&_MyTRC21.TransactOpts, owner)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Transactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "approve", spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Session) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Approve(&_MyTRC21.TransactOpts, spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21TransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Approve(&_MyTRC21.TransactOpts, spender, value)
+}
+
+// Burn is a paid mutator transaction binding the contract method 0xfe9d9303.
+//
+// Solidity: function burn(value uint256, data bytes) returns()
+func (_MyTRC21 *MyTRC21Transactor) Burn(opts *bind.TransactOpts, value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "burn", value, data)
+}
+
+// Burn is a paid mutator transaction binding the contract method 0xfe9d9303.
+//
+// Solidity: function burn(value uint256, data bytes) returns()
+func (_MyTRC21 *MyTRC21Session) Burn(value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Burn(&_MyTRC21.TransactOpts, value, data)
+}
+
+// Burn is a paid mutator transaction binding the contract method 0xfe9d9303.
+//
+// Solidity: function burn(value uint256, data bytes) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) Burn(value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Burn(&_MyTRC21.TransactOpts, value, data)
+}
+
+// ChangeRequirement is a paid mutator transaction binding the contract method 0xba51a6df.
+//
+// Solidity: function changeRequirement(_required uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) ChangeRequirement(opts *bind.TransactOpts, _required *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "changeRequirement", _required)
+}
+
+// ChangeRequirement is a paid mutator transaction binding the contract method 0xba51a6df.
+//
+// Solidity: function changeRequirement(_required uint256) returns()
+func (_MyTRC21 *MyTRC21Session) ChangeRequirement(_required *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ChangeRequirement(&_MyTRC21.TransactOpts, _required)
+}
+
+// ChangeRequirement is a paid mutator transaction binding the contract method 0xba51a6df.
+//
+// Solidity: function changeRequirement(_required uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) ChangeRequirement(_required *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ChangeRequirement(&_MyTRC21.TransactOpts, _required)
+}
+
+// ConfirmTransaction is a paid mutator transaction binding the contract method 0xc01a8c84.
+//
+// Solidity: function confirmTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) ConfirmTransaction(opts *bind.TransactOpts, transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "confirmTransaction", transactionId)
+}
+
+// ConfirmTransaction is a paid mutator transaction binding the contract method 0xc01a8c84.
+//
+// Solidity: function confirmTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Session) ConfirmTransaction(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ConfirmTransaction(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// ConfirmTransaction is a paid mutator transaction binding the contract method 0xc01a8c84.
+//
+// Solidity: function confirmTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) ConfirmTransaction(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ConfirmTransaction(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// ExecuteTransaction is a paid mutator transaction binding the contract method 0xee22610b.
+//
+// Solidity: function executeTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) ExecuteTransaction(opts *bind.TransactOpts, transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "executeTransaction", transactionId)
+}
+
+// ExecuteTransaction is a paid mutator transaction binding the contract method 0xee22610b.
+//
+// Solidity: function executeTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Session) ExecuteTransaction(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ExecuteTransaction(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// ExecuteTransaction is a paid mutator transaction binding the contract method 0xee22610b.
+//
+// Solidity: function executeTransaction(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) ExecuteTransaction(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ExecuteTransaction(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// RemoveOwner is a paid mutator transaction binding the contract method 0x173825d9.
+//
+// Solidity: function removeOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21Transactor) RemoveOwner(opts *bind.TransactOpts, owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "removeOwner", owner)
+}
+
+// RemoveOwner is a paid mutator transaction binding the contract method 0x173825d9.
+//
+// Solidity: function removeOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21Session) RemoveOwner(owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.RemoveOwner(&_MyTRC21.TransactOpts, owner)
+}
+
+// RemoveOwner is a paid mutator transaction binding the contract method 0x173825d9.
+//
+// Solidity: function removeOwner(owner address) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) RemoveOwner(owner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.RemoveOwner(&_MyTRC21.TransactOpts, owner)
+}
+
+// ReplaceOwner is a paid mutator transaction binding the contract method 0xe20056e6.
+//
+// Solidity: function replaceOwner(owner address, newOwner address) returns()
+func (_MyTRC21 *MyTRC21Transactor) ReplaceOwner(opts *bind.TransactOpts, owner common.Address, newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "replaceOwner", owner, newOwner)
+}
+
+// ReplaceOwner is a paid mutator transaction binding the contract method 0xe20056e6.
+//
+// Solidity: function replaceOwner(owner address, newOwner address) returns()
+func (_MyTRC21 *MyTRC21Session) ReplaceOwner(owner common.Address, newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ReplaceOwner(&_MyTRC21.TransactOpts, owner, newOwner)
+}
+
+// ReplaceOwner is a paid mutator transaction binding the contract method 0xe20056e6.
+//
+// Solidity: function replaceOwner(owner address, newOwner address) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) ReplaceOwner(owner common.Address, newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.ReplaceOwner(&_MyTRC21.TransactOpts, owner, newOwner)
+}
+
+// RevokeConfirmation is a paid mutator transaction binding the contract method 0x20ea8d86.
+//
+// Solidity: function revokeConfirmation(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) RevokeConfirmation(opts *bind.TransactOpts, transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "revokeConfirmation", transactionId)
+}
+
+// RevokeConfirmation is a paid mutator transaction binding the contract method 0x20ea8d86.
+//
+// Solidity: function revokeConfirmation(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21Session) RevokeConfirmation(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.RevokeConfirmation(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// RevokeConfirmation is a paid mutator transaction binding the contract method 0x20ea8d86.
+//
+// Solidity: function revokeConfirmation(transactionId uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) RevokeConfirmation(transactionId *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.RevokeConfirmation(&_MyTRC21.TransactOpts, transactionId)
+}
+
+// SetDepositFee is a paid mutator transaction binding the contract method 0x490ae210.
+//
+// Solidity: function setDepositFee(depositFee uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) SetDepositFee(opts *bind.TransactOpts, depositFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "setDepositFee", depositFee)
+}
+
+// SetDepositFee is a paid mutator transaction binding the contract method 0x490ae210.
+//
+// Solidity: function setDepositFee(depositFee uint256) returns()
+func (_MyTRC21 *MyTRC21Session) SetDepositFee(depositFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetDepositFee(&_MyTRC21.TransactOpts, depositFee)
+}
+
+// SetDepositFee is a paid mutator transaction binding the contract method 0x490ae210.
+//
+// Solidity: function setDepositFee(depositFee uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) SetDepositFee(depositFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetDepositFee(&_MyTRC21.TransactOpts, depositFee)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) SetMinFee(opts *bind.TransactOpts, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "setMinFee", value)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_MyTRC21 *MyTRC21Session) SetMinFee(value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetMinFee(&_MyTRC21.TransactOpts, value)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) SetMinFee(value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetMinFee(&_MyTRC21.TransactOpts, value)
+}
+
+// SetWithdrawFee is a paid mutator transaction binding the contract method 0xb6ac642a.
+//
+// Solidity: function setWithdrawFee(withdrawFee uint256) returns()
+func (_MyTRC21 *MyTRC21Transactor) SetWithdrawFee(opts *bind.TransactOpts, withdrawFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "setWithdrawFee", withdrawFee)
+}
+
+// SetWithdrawFee is a paid mutator transaction binding the contract method 0xb6ac642a.
+//
+// Solidity: function setWithdrawFee(withdrawFee uint256) returns()
+func (_MyTRC21 *MyTRC21Session) SetWithdrawFee(withdrawFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetWithdrawFee(&_MyTRC21.TransactOpts, withdrawFee)
+}
+
+// SetWithdrawFee is a paid mutator transaction binding the contract method 0xb6ac642a.
+//
+// Solidity: function setWithdrawFee(withdrawFee uint256) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) SetWithdrawFee(withdrawFee *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SetWithdrawFee(&_MyTRC21.TransactOpts, withdrawFee)
+}
+
+// SubmitTransaction is a paid mutator transaction binding the contract method 0xc6427474.
+//
+// Solidity: function submitTransaction(destination address, value uint256, data bytes) returns(transactionId uint256)
+func (_MyTRC21 *MyTRC21Transactor) SubmitTransaction(opts *bind.TransactOpts, destination common.Address, value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "submitTransaction", destination, value, data)
+}
+
+// SubmitTransaction is a paid mutator transaction binding the contract method 0xc6427474.
+//
+// Solidity: function submitTransaction(destination address, value uint256, data bytes) returns(transactionId uint256)
+func (_MyTRC21 *MyTRC21Session) SubmitTransaction(destination common.Address, value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SubmitTransaction(&_MyTRC21.TransactOpts, destination, value, data)
+}
+
+// SubmitTransaction is a paid mutator transaction binding the contract method 0xc6427474.
+//
+// Solidity: function submitTransaction(destination address, value uint256, data bytes) returns(transactionId uint256)
+func (_MyTRC21 *MyTRC21TransactorSession) SubmitTransaction(destination common.Address, value *big.Int, data []byte) (*types.Transaction, error) {
+ return _MyTRC21.Contract.SubmitTransaction(&_MyTRC21.TransactOpts, destination, value, data)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Transactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "transfer", to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Session) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Transfer(&_MyTRC21.TransactOpts, to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21TransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.Transfer(&_MyTRC21.TransactOpts, to, value)
+}
+
+// TransferContractIssuer is a paid mutator transaction binding the contract method 0xc28ce6ff.
+//
+// Solidity: function transferContractIssuer(newOwner address) returns()
+func (_MyTRC21 *MyTRC21Transactor) TransferContractIssuer(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "transferContractIssuer", newOwner)
+}
+
+// TransferContractIssuer is a paid mutator transaction binding the contract method 0xc28ce6ff.
+//
+// Solidity: function transferContractIssuer(newOwner address) returns()
+func (_MyTRC21 *MyTRC21Session) TransferContractIssuer(newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.TransferContractIssuer(&_MyTRC21.TransactOpts, newOwner)
+}
+
+// TransferContractIssuer is a paid mutator transaction binding the contract method 0xc28ce6ff.
+//
+// Solidity: function transferContractIssuer(newOwner address) returns()
+func (_MyTRC21 *MyTRC21TransactorSession) TransferContractIssuer(newOwner common.Address) (*types.Transaction, error) {
+ return _MyTRC21.Contract.TransferContractIssuer(&_MyTRC21.TransactOpts, newOwner)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.contract.Transact(opts, "transferFrom", from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21Session) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.TransferFrom(&_MyTRC21.TransactOpts, from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_MyTRC21 *MyTRC21TransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _MyTRC21.Contract.TransferFrom(&_MyTRC21.TransactOpts, from, to, value)
+}
+
+// MyTRC21ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the MyTRC21 contract.
+type MyTRC21ApprovalIterator struct {
+ Event *MyTRC21Approval // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21ApprovalIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21ApprovalIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21ApprovalIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Approval represents a Approval event raised by the MyTRC21 contract.
+type MyTRC21Approval struct {
+ Owner common.Address
+ Spender common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*MyTRC21ApprovalIterator, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21ApprovalIterator{contract: _MyTRC21.contract, event: "Approval", logs: logs, sub: sub}, nil
+}
+
+// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *MyTRC21Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Approval)
+ if err := _MyTRC21.contract.UnpackLog(event, "Approval", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21ConfirmationIterator is returned from FilterConfirmation and is used to iterate over the raw logs and unpacked data for Confirmation events raised by the MyTRC21 contract.
+type MyTRC21ConfirmationIterator struct {
+ Event *MyTRC21Confirmation // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21ConfirmationIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Confirmation)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Confirmation)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21ConfirmationIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21ConfirmationIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Confirmation represents a Confirmation event raised by the MyTRC21 contract.
+type MyTRC21Confirmation struct {
+ Sender common.Address
+ TransactionId *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterConfirmation is a free log retrieval operation binding the contract event 0x4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef.
+//
+// Solidity: event Confirmation(sender indexed address, transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterConfirmation(opts *bind.FilterOpts, sender []common.Address, transactionId []*big.Int) (*MyTRC21ConfirmationIterator, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Confirmation", senderRule, transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21ConfirmationIterator{contract: _MyTRC21.contract, event: "Confirmation", logs: logs, sub: sub}, nil
+}
+
+// WatchConfirmation is a free log subscription operation binding the contract event 0x4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef.
+//
+// Solidity: event Confirmation(sender indexed address, transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchConfirmation(opts *bind.WatchOpts, sink chan<- *MyTRC21Confirmation, sender []common.Address, transactionId []*big.Int) (event.Subscription, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Confirmation", senderRule, transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Confirmation)
+ if err := _MyTRC21.contract.UnpackLog(event, "Confirmation", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21ExecutionIterator is returned from FilterExecution and is used to iterate over the raw logs and unpacked data for Execution events raised by the MyTRC21 contract.
+type MyTRC21ExecutionIterator struct {
+ Event *MyTRC21Execution // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21ExecutionIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Execution)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Execution)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21ExecutionIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21ExecutionIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Execution represents a Execution event raised by the MyTRC21 contract.
+type MyTRC21Execution struct {
+ TransactionId *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterExecution is a free log retrieval operation binding the contract event 0x33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed75.
+//
+// Solidity: event Execution(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterExecution(opts *bind.FilterOpts, transactionId []*big.Int) (*MyTRC21ExecutionIterator, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Execution", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21ExecutionIterator{contract: _MyTRC21.contract, event: "Execution", logs: logs, sub: sub}, nil
+}
+
+// WatchExecution is a free log subscription operation binding the contract event 0x33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed75.
+//
+// Solidity: event Execution(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchExecution(opts *bind.WatchOpts, sink chan<- *MyTRC21Execution, transactionId []*big.Int) (event.Subscription, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Execution", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Execution)
+ if err := _MyTRC21.contract.UnpackLog(event, "Execution", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21ExecutionFailureIterator is returned from FilterExecutionFailure and is used to iterate over the raw logs and unpacked data for ExecutionFailure events raised by the MyTRC21 contract.
+type MyTRC21ExecutionFailureIterator struct {
+ Event *MyTRC21ExecutionFailure // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21ExecutionFailureIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21ExecutionFailure)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21ExecutionFailure)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21ExecutionFailureIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21ExecutionFailureIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21ExecutionFailure represents a ExecutionFailure event raised by the MyTRC21 contract.
+type MyTRC21ExecutionFailure struct {
+ TransactionId *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterExecutionFailure is a free log retrieval operation binding the contract event 0x526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b79236.
+//
+// Solidity: event ExecutionFailure(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterExecutionFailure(opts *bind.FilterOpts, transactionId []*big.Int) (*MyTRC21ExecutionFailureIterator, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "ExecutionFailure", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21ExecutionFailureIterator{contract: _MyTRC21.contract, event: "ExecutionFailure", logs: logs, sub: sub}, nil
+}
+
+// WatchExecutionFailure is a free log subscription operation binding the contract event 0x526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b79236.
+//
+// Solidity: event ExecutionFailure(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchExecutionFailure(opts *bind.WatchOpts, sink chan<- *MyTRC21ExecutionFailure, transactionId []*big.Int) (event.Subscription, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "ExecutionFailure", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21ExecutionFailure)
+ if err := _MyTRC21.contract.UnpackLog(event, "ExecutionFailure", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21FeeIterator is returned from FilterFee and is used to iterate over the raw logs and unpacked data for Fee events raised by the MyTRC21 contract.
+type MyTRC21FeeIterator struct {
+ Event *MyTRC21Fee // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21FeeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21FeeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21FeeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Fee represents a Fee event raised by the MyTRC21 contract.
+type MyTRC21Fee struct {
+ From common.Address
+ To common.Address
+ Issuer common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterFee is a free log retrieval operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterFee(opts *bind.FilterOpts, from []common.Address, to []common.Address, issuer []common.Address) (*MyTRC21FeeIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21FeeIterator{contract: _MyTRC21.contract, event: "Fee", logs: logs, sub: sub}, nil
+}
+
+// WatchFee is a free log subscription operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchFee(opts *bind.WatchOpts, sink chan<- *MyTRC21Fee, from []common.Address, to []common.Address, issuer []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Fee)
+ if err := _MyTRC21.contract.UnpackLog(event, "Fee", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21OwnerAdditionIterator is returned from FilterOwnerAddition and is used to iterate over the raw logs and unpacked data for OwnerAddition events raised by the MyTRC21 contract.
+type MyTRC21OwnerAdditionIterator struct {
+ Event *MyTRC21OwnerAddition // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21OwnerAdditionIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21OwnerAddition)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21OwnerAddition)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21OwnerAdditionIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21OwnerAdditionIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21OwnerAddition represents a OwnerAddition event raised by the MyTRC21 contract.
+type MyTRC21OwnerAddition struct {
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterOwnerAddition is a free log retrieval operation binding the contract event 0xf39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d.
+//
+// Solidity: event OwnerAddition(owner indexed address)
+func (_MyTRC21 *MyTRC21Filterer) FilterOwnerAddition(opts *bind.FilterOpts, owner []common.Address) (*MyTRC21OwnerAdditionIterator, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "OwnerAddition", ownerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21OwnerAdditionIterator{contract: _MyTRC21.contract, event: "OwnerAddition", logs: logs, sub: sub}, nil
+}
+
+// WatchOwnerAddition is a free log subscription operation binding the contract event 0xf39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d.
+//
+// Solidity: event OwnerAddition(owner indexed address)
+func (_MyTRC21 *MyTRC21Filterer) WatchOwnerAddition(opts *bind.WatchOpts, sink chan<- *MyTRC21OwnerAddition, owner []common.Address) (event.Subscription, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "OwnerAddition", ownerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21OwnerAddition)
+ if err := _MyTRC21.contract.UnpackLog(event, "OwnerAddition", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21OwnerRemovalIterator is returned from FilterOwnerRemoval and is used to iterate over the raw logs and unpacked data for OwnerRemoval events raised by the MyTRC21 contract.
+type MyTRC21OwnerRemovalIterator struct {
+ Event *MyTRC21OwnerRemoval // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21OwnerRemovalIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21OwnerRemoval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21OwnerRemoval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21OwnerRemovalIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21OwnerRemovalIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21OwnerRemoval represents a OwnerRemoval event raised by the MyTRC21 contract.
+type MyTRC21OwnerRemoval struct {
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterOwnerRemoval is a free log retrieval operation binding the contract event 0x8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b90.
+//
+// Solidity: event OwnerRemoval(owner indexed address)
+func (_MyTRC21 *MyTRC21Filterer) FilterOwnerRemoval(opts *bind.FilterOpts, owner []common.Address) (*MyTRC21OwnerRemovalIterator, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "OwnerRemoval", ownerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21OwnerRemovalIterator{contract: _MyTRC21.contract, event: "OwnerRemoval", logs: logs, sub: sub}, nil
+}
+
+// WatchOwnerRemoval is a free log subscription operation binding the contract event 0x8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b90.
+//
+// Solidity: event OwnerRemoval(owner indexed address)
+func (_MyTRC21 *MyTRC21Filterer) WatchOwnerRemoval(opts *bind.WatchOpts, sink chan<- *MyTRC21OwnerRemoval, owner []common.Address) (event.Subscription, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "OwnerRemoval", ownerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21OwnerRemoval)
+ if err := _MyTRC21.contract.UnpackLog(event, "OwnerRemoval", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21RequirementChangeIterator is returned from FilterRequirementChange and is used to iterate over the raw logs and unpacked data for RequirementChange events raised by the MyTRC21 contract.
+type MyTRC21RequirementChangeIterator struct {
+ Event *MyTRC21RequirementChange // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21RequirementChangeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21RequirementChange)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21RequirementChange)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21RequirementChangeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21RequirementChangeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21RequirementChange represents a RequirementChange event raised by the MyTRC21 contract.
+type MyTRC21RequirementChange struct {
+ Required *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterRequirementChange is a free log retrieval operation binding the contract event 0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a.
+//
+// Solidity: event RequirementChange(required uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterRequirementChange(opts *bind.FilterOpts) (*MyTRC21RequirementChangeIterator, error) {
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "RequirementChange")
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21RequirementChangeIterator{contract: _MyTRC21.contract, event: "RequirementChange", logs: logs, sub: sub}, nil
+}
+
+// WatchRequirementChange is a free log subscription operation binding the contract event 0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a.
+//
+// Solidity: event RequirementChange(required uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchRequirementChange(opts *bind.WatchOpts, sink chan<- *MyTRC21RequirementChange) (event.Subscription, error) {
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "RequirementChange")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21RequirementChange)
+ if err := _MyTRC21.contract.UnpackLog(event, "RequirementChange", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21RevocationIterator is returned from FilterRevocation and is used to iterate over the raw logs and unpacked data for Revocation events raised by the MyTRC21 contract.
+type MyTRC21RevocationIterator struct {
+ Event *MyTRC21Revocation // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21RevocationIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Revocation)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Revocation)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21RevocationIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21RevocationIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Revocation represents a Revocation event raised by the MyTRC21 contract.
+type MyTRC21Revocation struct {
+ Sender common.Address
+ TransactionId *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterRevocation is a free log retrieval operation binding the contract event 0xf6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e9.
+//
+// Solidity: event Revocation(sender indexed address, transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterRevocation(opts *bind.FilterOpts, sender []common.Address, transactionId []*big.Int) (*MyTRC21RevocationIterator, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Revocation", senderRule, transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21RevocationIterator{contract: _MyTRC21.contract, event: "Revocation", logs: logs, sub: sub}, nil
+}
+
+// WatchRevocation is a free log subscription operation binding the contract event 0xf6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e9.
+//
+// Solidity: event Revocation(sender indexed address, transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchRevocation(opts *bind.WatchOpts, sink chan<- *MyTRC21Revocation, sender []common.Address, transactionId []*big.Int) (event.Subscription, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Revocation", senderRule, transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Revocation)
+ if err := _MyTRC21.contract.UnpackLog(event, "Revocation", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21SubmissionIterator is returned from FilterSubmission and is used to iterate over the raw logs and unpacked data for Submission events raised by the MyTRC21 contract.
+type MyTRC21SubmissionIterator struct {
+ Event *MyTRC21Submission // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21SubmissionIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Submission)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Submission)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21SubmissionIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21SubmissionIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Submission represents a Submission event raised by the MyTRC21 contract.
+type MyTRC21Submission struct {
+ TransactionId *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterSubmission is a free log retrieval operation binding the contract event 0xc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e51.
+//
+// Solidity: event Submission(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterSubmission(opts *bind.FilterOpts, transactionId []*big.Int) (*MyTRC21SubmissionIterator, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Submission", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21SubmissionIterator{contract: _MyTRC21.contract, event: "Submission", logs: logs, sub: sub}, nil
+}
+
+// WatchSubmission is a free log subscription operation binding the contract event 0xc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e51.
+//
+// Solidity: event Submission(transactionId indexed uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchSubmission(opts *bind.WatchOpts, sink chan<- *MyTRC21Submission, transactionId []*big.Int) (event.Subscription, error) {
+
+ var transactionIdRule []interface{}
+ for _, transactionIdItem := range transactionId {
+ transactionIdRule = append(transactionIdRule, transactionIdItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Submission", transactionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Submission)
+ if err := _MyTRC21.contract.UnpackLog(event, "Submission", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21TokenBurnIterator is returned from FilterTokenBurn and is used to iterate over the raw logs and unpacked data for TokenBurn events raised by the MyTRC21 contract.
+type MyTRC21TokenBurnIterator struct {
+ Event *MyTRC21TokenBurn // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21TokenBurnIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21TokenBurn)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21TokenBurn)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21TokenBurnIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21TokenBurnIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21TokenBurn represents a TokenBurn event raised by the MyTRC21 contract.
+type MyTRC21TokenBurn struct {
+ BurnID *big.Int
+ Burner common.Address
+ Value *big.Int
+ Data []byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTokenBurn is a free log retrieval operation binding the contract event 0x6905852b196f81e7e03058512a599446c358027fc943c1e193b6649a39379bb5.
+//
+// Solidity: event TokenBurn(burnID indexed uint256, burner indexed address, value uint256, data bytes)
+func (_MyTRC21 *MyTRC21Filterer) FilterTokenBurn(opts *bind.FilterOpts, burnID []*big.Int, burner []common.Address) (*MyTRC21TokenBurnIterator, error) {
+
+ var burnIDRule []interface{}
+ for _, burnIDItem := range burnID {
+ burnIDRule = append(burnIDRule, burnIDItem)
+ }
+ var burnerRule []interface{}
+ for _, burnerItem := range burner {
+ burnerRule = append(burnerRule, burnerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "TokenBurn", burnIDRule, burnerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21TokenBurnIterator{contract: _MyTRC21.contract, event: "TokenBurn", logs: logs, sub: sub}, nil
+}
+
+// WatchTokenBurn is a free log subscription operation binding the contract event 0x6905852b196f81e7e03058512a599446c358027fc943c1e193b6649a39379bb5.
+//
+// Solidity: event TokenBurn(burnID indexed uint256, burner indexed address, value uint256, data bytes)
+func (_MyTRC21 *MyTRC21Filterer) WatchTokenBurn(opts *bind.WatchOpts, sink chan<- *MyTRC21TokenBurn, burnID []*big.Int, burner []common.Address) (event.Subscription, error) {
+
+ var burnIDRule []interface{}
+ for _, burnIDItem := range burnID {
+ burnIDRule = append(burnIDRule, burnIDItem)
+ }
+ var burnerRule []interface{}
+ for _, burnerItem := range burner {
+ burnerRule = append(burnerRule, burnerItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "TokenBurn", burnIDRule, burnerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21TokenBurn)
+ if err := _MyTRC21.contract.UnpackLog(event, "TokenBurn", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// MyTRC21TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the MyTRC21 contract.
+type MyTRC21TransferIterator struct {
+ Event *MyTRC21Transfer // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *MyTRC21TransferIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(MyTRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *MyTRC21TransferIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *MyTRC21TransferIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// MyTRC21Transfer represents a Transfer event raised by the MyTRC21 contract.
+type MyTRC21Transfer struct {
+ From common.Address
+ To common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MyTRC21TransferIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.FilterLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &MyTRC21TransferIterator{contract: _MyTRC21.contract, event: "Transfer", logs: logs, sub: sub}, nil
+}
+
+// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_MyTRC21 *MyTRC21Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *MyTRC21Transfer, from []common.Address, to []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _MyTRC21.contract.WatchLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(MyTRC21Transfer)
+ if err := _MyTRC21.contract.UnpackLog(event, "Transfer", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// TRC21ABI is the input ABI used to generate the binding from.
+const TRC21ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"estimateFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"issuer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setMinFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"symbol\",\"type\":\"string\"},{\"name\":\"decimals\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"}]"
+
+// TRC21Bin is the compiled bytecode used for deploying new contracts.
+const TRC21Bin = `0x608060405234801561001057600080fd5b50604051610a2c380380610a2c83398101604090815281516020808401519284015191840180519094939093019261004e916005919086019061007f565b50815161006290600690602085019061007f565b506007805460ff191660ff929092169190911790555061011a9050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100c057805160ff19168380011785556100ed565b828001600101855582156100ed579182015b828111156100ed5782518255916020019190600101906100d2565b506100f99291506100fd565b5090565b61011791905b808211156100f95760008155600101610103565b90565b610903806101296000396000f3006080604052600436106100c45763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100c9578063095ea7b314610153578063127e8e4d1461018b57806318160ddd146101b55780631d143848146101ca57806323b872dd146101fb57806324ec759014610225578063313ce5671461023a57806331ac99201461026557806370a082311461027f57806395d89b41146102a0578063a9059cbb146102b5578063dd62ed3e146102d9575b600080fd5b3480156100d557600080fd5b506100de610300565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610118578181015183820152602001610100565b50505050905090810190601f1680156101455780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015f57600080fd5b50610177600160a060020a0360043516602435610396565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a3600435610450565b60408051918252519081900360200190f35b3480156101c157600080fd5b506101a361047c565b3480156101d657600080fd5b506101df610482565b60408051600160a060020a039092168252519081900360200190f35b34801561020757600080fd5b50610177600160a060020a0360043581169060243516604435610491565b34801561023157600080fd5b506101a36105d5565b34801561024657600080fd5b5061024f6105db565b6040805160ff9092168252519081900360200190f35b34801561027157600080fd5b5061027d6004356105e4565b005b34801561028b57600080fd5b506101a3600160a060020a0360043516610607565b3480156102ac57600080fd5b506100de610622565b3480156102c157600080fd5b50610177600160a060020a0360043516602435610683565b3480156102e557600080fd5b506101a3600160a060020a0360043581169060243516610757565b60058054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561038c5780601f106103615761010080835404028352916020019161038c565b820191906000526020600020905b81548152906001019060200180831161036f57829003601f168201915b5050505050905090565b6000600160a060020a03831615156103ad57600080fd5b6001543360009081526020819052604090205410156103cb57600080fd5b336000818152600360209081526040808320600160a060020a038881168552925290912084905560025460015461040793929190911690610782565b604080518381529051600160a060020a0385169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a350600192915050565b6001546000906104769061046a848463ffffffff61087416565b9063ffffffff6108a916565b92915050565b60045490565b600254600160a060020a031690565b6000806104a9600154846108a990919063ffffffff16565b600160a060020a0386166000908152602081905260409020549091508111156104d157600080fd5b600160a060020a038516600090815260036020908152604080832033845290915290205483111561050157600080fd5b600160a060020a0385166000908152600360209081526040808320338452909152902054610535908263ffffffff6108bb16565b600160a060020a0386166000908152600360209081526040808320338452909152902055610564858585610782565b600254600154610581918791600160a060020a0390911690610782565b6002546001546040805191825251600160a060020a039283169287169133917ffcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd999181900360200190a4506001949350505050565b60015490565b60075460ff1690565b600254600160a060020a031633146105fb57600080fd5b610604816108d2565b50565b600160a060020a031660009081526020819052604090205490565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561038c5780601f106103615761010080835404028352916020019161038c565b600080600160a060020a038416151561069b57600080fd5b6001546106af90849063ffffffff6108a916565b336000908152602081905260409020549091508111156106ce57600080fd5b6106d9338585610782565b6000600154111561074b57600254600154610701913391600160a060020a0390911690610782565b6002546001546040805191825251600160a060020a039283169287169133917ffcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd999181900360200190a45b600191505b5092915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b600160a060020a0383166000908152602081905260409020548111156107a757600080fd5b600160a060020a03821615156107bc57600080fd5b600160a060020a0383166000908152602081905260409020546107e5908263ffffffff6108bb16565b600160a060020a03808516600090815260208190526040808220939093559084168152205461081a908263ffffffff6108a916565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000808315156108875760009150610750565b5082820282848281151561089757fe5b04146108a257600080fd5b9392505050565b6000828201838110156108a257600080fd5b600080838311156108cb57600080fd5b5050900390565b6001555600a165627a7a723058206c24d49045155ad83d904de717409715bdb93edbc379076a4a1d5f03d3ae00900029`
+
+// DeployTRC21 deploys a new Ethereum contract, binding an instance of TRC21 to it.
+func DeployTRC21(auth *bind.TransactOpts, backend bind.ContractBackend, name string, symbol string, decimals uint8) (common.Address, *types.Transaction, *TRC21, error) {
+ parsed, err := abi.JSON(strings.NewReader(TRC21ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TRC21Bin), backend, name, symbol, decimals)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &TRC21{TRC21Caller: TRC21Caller{contract: contract}, TRC21Transactor: TRC21Transactor{contract: contract}, TRC21Filterer: TRC21Filterer{contract: contract}}, nil
+}
+
+// TRC21 is an auto generated Go binding around an Ethereum contract.
+type TRC21 struct {
+ TRC21Caller // Read-only binding to the contract
+ TRC21Transactor // Write-only binding to the contract
+ TRC21Filterer // Log filterer for contract events
+}
+
+// TRC21Caller is an auto generated read-only Go binding around an Ethereum contract.
+type TRC21Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type TRC21Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type TRC21Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type TRC21Session struct {
+ Contract *TRC21 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// TRC21CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type TRC21CallerSession struct {
+ Contract *TRC21Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// TRC21TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type TRC21TransactorSession struct {
+ Contract *TRC21Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// TRC21Raw is an auto generated low-level Go binding around an Ethereum contract.
+type TRC21Raw struct {
+ Contract *TRC21 // Generic contract binding to access the raw methods on
+}
+
+// TRC21CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type TRC21CallerRaw struct {
+ Contract *TRC21Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// TRC21TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type TRC21TransactorRaw struct {
+ Contract *TRC21Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewTRC21 creates a new instance of TRC21, bound to a specific deployed contract.
+func NewTRC21(address common.Address, backend bind.ContractBackend) (*TRC21, error) {
+ contract, err := bindTRC21(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21{TRC21Caller: TRC21Caller{contract: contract}, TRC21Transactor: TRC21Transactor{contract: contract}, TRC21Filterer: TRC21Filterer{contract: contract}}, nil
+}
+
+// NewTRC21Caller creates a new read-only instance of TRC21, bound to a specific deployed contract.
+func NewTRC21Caller(address common.Address, caller bind.ContractCaller) (*TRC21Caller, error) {
+ contract, err := bindTRC21(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21Caller{contract: contract}, nil
+}
+
+// NewTRC21Transactor creates a new write-only instance of TRC21, bound to a specific deployed contract.
+func NewTRC21Transactor(address common.Address, transactor bind.ContractTransactor) (*TRC21Transactor, error) {
+ contract, err := bindTRC21(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21Transactor{contract: contract}, nil
+}
+
+// NewTRC21Filterer creates a new log filterer instance of TRC21, bound to a specific deployed contract.
+func NewTRC21Filterer(address common.Address, filterer bind.ContractFilterer) (*TRC21Filterer, error) {
+ contract, err := bindTRC21(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21Filterer{contract: contract}, nil
+}
+
+// bindTRC21 binds a generic wrapper to an already deployed contract.
+func bindTRC21(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(TRC21ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_TRC21 *TRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _TRC21.Contract.TRC21Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_TRC21 *TRC21Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TRC21.Contract.TRC21Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TRC21 *TRC21Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TRC21.Contract.TRC21Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_TRC21 *TRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _TRC21.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_TRC21 *TRC21TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TRC21.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TRC21 *TRC21TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TRC21.Contract.contract.Transact(opts, method, params...)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_TRC21 *TRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "allowance", owner, spender)
+ return *ret0, err
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_TRC21 *TRC21Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _TRC21.Contract.Allowance(&_TRC21.CallOpts, owner, spender)
+}
+
+// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
+//
+// Solidity: function allowance(owner address, spender address) constant returns(uint256)
+func (_TRC21 *TRC21CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
+ return _TRC21.Contract.Allowance(&_TRC21.CallOpts, owner, spender)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_TRC21 *TRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "balanceOf", owner)
+ return *ret0, err
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_TRC21 *TRC21Session) BalanceOf(owner common.Address) (*big.Int, error) {
+ return _TRC21.Contract.BalanceOf(&_TRC21.CallOpts, owner)
+}
+
+// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
+//
+// Solidity: function balanceOf(owner address) constant returns(uint256)
+func (_TRC21 *TRC21CallerSession) BalanceOf(owner common.Address) (*big.Int, error) {
+ return _TRC21.Contract.BalanceOf(&_TRC21.CallOpts, owner)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_TRC21 *TRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) {
+ var (
+ ret0 = new(uint8)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "decimals")
+ return *ret0, err
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_TRC21 *TRC21Session) Decimals() (uint8, error) {
+ return _TRC21.Contract.Decimals(&_TRC21.CallOpts)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() constant returns(uint8)
+func (_TRC21 *TRC21CallerSession) Decimals() (uint8, error) {
+ return _TRC21.Contract.Decimals(&_TRC21.CallOpts)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_TRC21 *TRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "estimateFee", value)
+ return *ret0, err
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_TRC21 *TRC21Session) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _TRC21.Contract.EstimateFee(&_TRC21.CallOpts, value)
+}
+
+// EstimateFee is a free data retrieval call binding the contract method 0x127e8e4d.
+//
+// Solidity: function estimateFee(value uint256) constant returns(uint256)
+func (_TRC21 *TRC21CallerSession) EstimateFee(value *big.Int) (*big.Int, error) {
+ return _TRC21.Contract.EstimateFee(&_TRC21.CallOpts, value)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_TRC21 *TRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "issuer")
+ return *ret0, err
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_TRC21 *TRC21Session) Issuer() (common.Address, error) {
+ return _TRC21.Contract.Issuer(&_TRC21.CallOpts)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_TRC21 *TRC21CallerSession) Issuer() (common.Address, error) {
+ return _TRC21.Contract.Issuer(&_TRC21.CallOpts)
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_TRC21 *TRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "minFee")
+ return *ret0, err
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_TRC21 *TRC21Session) MinFee() (*big.Int, error) {
+ return _TRC21.Contract.MinFee(&_TRC21.CallOpts)
+}
+
+// MinFee is a free data retrieval call binding the contract method 0x24ec7590.
+//
+// Solidity: function minFee() constant returns(uint256)
+func (_TRC21 *TRC21CallerSession) MinFee() (*big.Int, error) {
+ return _TRC21.Contract.MinFee(&_TRC21.CallOpts)
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_TRC21 *TRC21Caller) Name(opts *bind.CallOpts) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "name")
+ return *ret0, err
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_TRC21 *TRC21Session) Name() (string, error) {
+ return _TRC21.Contract.Name(&_TRC21.CallOpts)
+}
+
+// Name is a free data retrieval call binding the contract method 0x06fdde03.
+//
+// Solidity: function name() constant returns(string)
+func (_TRC21 *TRC21CallerSession) Name() (string, error) {
+ return _TRC21.Contract.Name(&_TRC21.CallOpts)
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_TRC21 *TRC21Caller) Symbol(opts *bind.CallOpts) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "symbol")
+ return *ret0, err
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_TRC21 *TRC21Session) Symbol() (string, error) {
+ return _TRC21.Contract.Symbol(&_TRC21.CallOpts)
+}
+
+// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
+//
+// Solidity: function symbol() constant returns(string)
+func (_TRC21 *TRC21CallerSession) Symbol() (string, error) {
+ return _TRC21.Contract.Symbol(&_TRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_TRC21 *TRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21.contract.Call(opts, out, "totalSupply")
+ return *ret0, err
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_TRC21 *TRC21Session) TotalSupply() (*big.Int, error) {
+ return _TRC21.Contract.TotalSupply(&_TRC21.CallOpts)
+}
+
+// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
+//
+// Solidity: function totalSupply() constant returns(uint256)
+func (_TRC21 *TRC21CallerSession) TotalSupply() (*big.Int, error) {
+ return _TRC21.Contract.TotalSupply(&_TRC21.CallOpts)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_TRC21 *TRC21Transactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.contract.Transact(opts, "approve", spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_TRC21 *TRC21Session) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.Approve(&_TRC21.TransactOpts, spender, value)
+}
+
+// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
+//
+// Solidity: function approve(spender address, value uint256) returns(bool)
+func (_TRC21 *TRC21TransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.Approve(&_TRC21.TransactOpts, spender, value)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_TRC21 *TRC21Transactor) SetMinFee(opts *bind.TransactOpts, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.contract.Transact(opts, "setMinFee", value)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_TRC21 *TRC21Session) SetMinFee(value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.SetMinFee(&_TRC21.TransactOpts, value)
+}
+
+// SetMinFee is a paid mutator transaction binding the contract method 0x31ac9920.
+//
+// Solidity: function setMinFee(value uint256) returns()
+func (_TRC21 *TRC21TransactorSession) SetMinFee(value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.SetMinFee(&_TRC21.TransactOpts, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_TRC21 *TRC21Transactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.contract.Transact(opts, "transfer", to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_TRC21 *TRC21Session) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.Transfer(&_TRC21.TransactOpts, to, value)
+}
+
+// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
+//
+// Solidity: function transfer(to address, value uint256) returns(bool)
+func (_TRC21 *TRC21TransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.Transfer(&_TRC21.TransactOpts, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_TRC21 *TRC21Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.contract.Transact(opts, "transferFrom", from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_TRC21 *TRC21Session) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.TransferFrom(&_TRC21.TransactOpts, from, to, value)
+}
+
+// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
+//
+// Solidity: function transferFrom(from address, to address, value uint256) returns(bool)
+func (_TRC21 *TRC21TransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) {
+ return _TRC21.Contract.TransferFrom(&_TRC21.TransactOpts, from, to, value)
+}
+
+// TRC21ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the TRC21 contract.
+type TRC21ApprovalIterator struct {
+ Event *TRC21Approval // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *TRC21ApprovalIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Approval)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *TRC21ApprovalIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TRC21ApprovalIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TRC21Approval represents a Approval event raised by the TRC21 contract.
+type TRC21Approval struct {
+ Owner common.Address
+ Spender common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TRC21ApprovalIterator, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _TRC21.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21ApprovalIterator{contract: _TRC21.contract, event: "Approval", logs: logs, sub: sub}, nil
+}
+
+// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
+//
+// Solidity: event Approval(owner indexed address, spender indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TRC21Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) {
+
+ var ownerRule []interface{}
+ for _, ownerItem := range owner {
+ ownerRule = append(ownerRule, ownerItem)
+ }
+ var spenderRule []interface{}
+ for _, spenderItem := range spender {
+ spenderRule = append(spenderRule, spenderItem)
+ }
+
+ logs, sub, err := _TRC21.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(TRC21Approval)
+ if err := _TRC21.contract.UnpackLog(event, "Approval", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// TRC21FeeIterator is returned from FilterFee and is used to iterate over the raw logs and unpacked data for Fee events raised by the TRC21 contract.
+type TRC21FeeIterator struct {
+ Event *TRC21Fee // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *TRC21FeeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Fee)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *TRC21FeeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TRC21FeeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TRC21Fee represents a Fee event raised by the TRC21 contract.
+type TRC21Fee struct {
+ From common.Address
+ To common.Address
+ Issuer common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterFee is a free log retrieval operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) FilterFee(opts *bind.FilterOpts, from []common.Address, to []common.Address, issuer []common.Address) (*TRC21FeeIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _TRC21.contract.FilterLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21FeeIterator{contract: _TRC21.contract, event: "Fee", logs: logs, sub: sub}, nil
+}
+
+// WatchFee is a free log subscription operation binding the contract event 0xfcf5b3276434181e3c48bd3fe569b8939808f11e845d4b963693b9d7dbd6dd99.
+//
+// Solidity: event Fee(from indexed address, to indexed address, issuer indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) WatchFee(opts *bind.WatchOpts, sink chan<- *TRC21Fee, from []common.Address, to []common.Address, issuer []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+
+ logs, sub, err := _TRC21.contract.WatchLogs(opts, "Fee", fromRule, toRule, issuerRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(TRC21Fee)
+ if err := _TRC21.contract.UnpackLog(event, "Fee", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// TRC21TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the TRC21 contract.
+type TRC21TransferIterator struct {
+ Event *TRC21Transfer // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *TRC21TransferIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21Transfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *TRC21TransferIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TRC21TransferIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TRC21Transfer represents a Transfer event raised by the TRC21 contract.
+type TRC21Transfer struct {
+ From common.Address
+ To common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TRC21TransferIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _TRC21.contract.FilterLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21TransferIterator{contract: _TRC21.contract, event: "Transfer", logs: logs, sub: sub}, nil
+}
+
+// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
+//
+// Solidity: event Transfer(from indexed address, to indexed address, value uint256)
+func (_TRC21 *TRC21Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TRC21Transfer, from []common.Address, to []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _TRC21.contract.WatchLogs(opts, "Transfer", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(TRC21Transfer)
+ if err := _TRC21.contract.UnpackLog(event, "Transfer", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/contracts/XDCx/contract/TRC21.sol b/contracts/XDCx/contract/TRC21.sol
new file mode 100644
index 0000000000..8bc2e86988
--- /dev/null
+++ b/contracts/XDCx/contract/TRC21.sol
@@ -0,0 +1,674 @@
+pragma solidity ^0.4.24;
+
+import "./SafeMath.sol";
+
+/**
+ * @title TRC21 interface
+ */
+interface ITRC21 {
+ function totalSupply() external view returns (uint256);
+
+ function balanceOf(address who) external view returns (uint256);
+
+ function issuer() external view returns (address);
+
+ function decimals() external view returns (uint8);
+
+ function estimateFee(uint256 value) external view returns (uint256);
+
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ function transfer(address to, uint256 value) external returns (bool);
+
+ function approve(address spender, uint256 value) external returns (bool);
+
+ function transferFrom(address from, address to, uint256 value) external returns (bool);
+
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+
+ event Fee(address indexed from, address indexed to, address indexed issuer, uint256 value);
+}
+
+/**
+ * @title Standard TRC21 token
+ * @dev Implementation of the basic standard token.
+ */
+contract TRC21 is ITRC21 {
+ using SafeMath for uint256;
+
+ mapping (address => uint256) private _balances;
+ uint256 private _minFee;
+ address private _issuer;
+ mapping (address => mapping (address => uint256)) private _allowed;
+ uint256 private _totalSupply;
+
+ string private _name;
+ string private _symbol;
+ uint8 private _decimals;
+
+ constructor (string memory name, string memory symbol, uint8 decimals) public {
+ _name = name;
+ _symbol = symbol;
+ _decimals = decimals;
+ }
+
+ function name() public view returns (string) {
+ return _name;
+ }
+
+ function symbol() public view returns (string) {
+ return _symbol;
+ }
+
+ function decimals() public view returns (uint8) {
+ return _decimals;
+ }
+
+ /**
+ * @dev Total number of tokens in existence
+ */
+ function totalSupply() public view returns (uint256) {
+ return _totalSupply;
+ }
+
+ /**
+ * @dev The amount fee that will be lost when transferring.
+ */
+ function minFee() public view returns (uint256) {
+ return _minFee;
+ }
+
+ /**
+ * @dev token's foundation
+ */
+ function issuer() public view returns (address) {
+ return _issuer;
+ }
+
+ /**
+ * @dev Gets the balance of the specified address.
+ * @param owner The address to query the balance of.
+ * @return An uint256 representing the amount owned by the passed address.
+ */
+ function balanceOf(address owner) public view returns (uint256) {
+ return _balances[owner];
+ }
+
+ /**
+ * @dev Estimate transaction fee.
+ * @param value amount tokens sent
+ */
+ function estimateFee(uint256 value) public view returns (uint256) {
+ return value.mul(0).add(_minFee);
+ }
+
+ function setMinFee(uint256 value) public {
+ require(msg.sender == _issuer);
+ _changeMinFee(value);
+ }
+
+ /**
+ * @dev Function to check the amount of tokens that an owner allowed to a spender.
+ * @param owner address The address which owns the funds.
+ * @param spender address The address which will spend the funds.
+ * @return A uint256 specifying the amount of tokens still available for the spender.
+ */
+ function allowance(address owner,address spender) public view returns (uint256){
+ return _allowed[owner][spender];
+ }
+
+ /**
+ * @dev Transfer token for a specified address
+ * @param to The address to transfer to.
+ * @param value The amount to be transferred.
+ */
+ function transfer(address to, uint256 value) public returns (bool) {
+ require(to != address(0));
+ uint256 total = value.add(_minFee);
+ require(total <= _balances[msg.sender]);
+ _transfer(msg.sender, to, value);
+ if (_minFee > 0) {
+ _transfer(msg.sender, _issuer, _minFee);
+ emit Fee(msg.sender, to, _issuer, _minFee);
+ }
+ return true;
+ }
+
+ /**
+ * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
+ * Beware that changing an allowance with this method brings the risk that someone may use both the old
+ * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
+ * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
+ * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
+ * @param spender The address which will spend the funds.
+ * @param value The amount of tokens to be spent.
+ */
+ function approve(address spender, uint256 value) public returns (bool) {
+ require(spender != address(0));
+ require(_balances[msg.sender] >= _minFee);
+ _allowed[msg.sender][spender] = value;
+ _transfer(msg.sender, _issuer, _minFee);
+ emit Approval(msg.sender, spender, value);
+ return true;
+ }
+
+ /**
+ * @dev Transfer tokens from one address to another
+ * @param from address The address which you want to send tokens from
+ * @param to address The address which you want to transfer to
+ * @param value uint256 the amount of tokens to be transferred
+ */
+ function transferFrom(address from, address to, uint256 value) public returns (bool) {
+ uint256 total = value.add(_minFee);
+ require(total <= _balances[from]);
+ require(value <= _allowed[from][msg.sender]); //msg.sender should be allowed to transfer maximum of value amount
+
+ _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(total);
+ _transfer(from, to, value);
+ _transfer(from, _issuer, _minFee);
+ emit Fee(msg.sender, to, _issuer, _minFee);
+ return true;
+ }
+
+ /**
+ * @dev Transfer token for a specified addresses
+ * @param from The address to transfer from.
+ * @param to The address to transfer to.
+ * @param value The amount to be transferred.
+ */
+ function _transfer(address from, address to, uint256 value) internal {
+ require(value <= _balances[from]);
+ require(to != address(0));
+ _balances[from] = _balances[from].sub(value);
+ _balances[to] = _balances[to].add(value);
+ emit Transfer(from, to, value);
+ }
+
+ /**
+ * @dev Internal function that mints an amount of the token and assigns it to
+ * an account. This encapsulates the modification of balances such that the
+ * proper events are emitted.
+ * @param account The account that will receive the created tokens.
+ * @param value The amount that will be created.
+ */
+ function _mint(address account, uint256 value) internal {
+ require(account != 0);
+ _totalSupply = _totalSupply.add(value);
+ _balances[account] = _balances[account].add(value);
+ emit Transfer(address(0), account, value);
+ }
+
+ /**
+ * @dev Internal function that burns an amount of the token of a given
+ * account.
+ * @param account The account whose tokens will be burnt.
+ * @param value The amount that will be burnt.
+ */
+ function _burn(address account, uint256 value) internal {
+ require(account != 0);
+ require(value <= _balances[account]);
+
+ _totalSupply = _totalSupply.sub(value);
+ _balances[account] = _balances[account].sub(value);
+ emit Transfer(account, address(0), value);
+ }
+
+ /**
+ * @dev Transfers token's foundation to new issuer
+ * @param newIssuer The address to transfer ownership to.
+ */
+ function _changeIssuer(address newIssuer) internal {
+ require(newIssuer != address(0));
+ _issuer = newIssuer;
+ }
+
+ /**
+ * @dev Change minFee
+ * @param value minFee
+ */
+ function _changeMinFee(uint256 value) internal {
+ _minFee = value;
+ }
+}
+
+//Wrap token based on multisig wallet that only mints new token if there are user deposits
+contract MyTRC21 is TRC21 {
+ /*
+ * Events
+ */
+ // event TxBurn(uint indexed transactionId);
+ event Confirmation(address indexed sender, uint indexed transactionId);
+ event Revocation(address indexed sender, uint indexed transactionId);
+ event Submission(uint indexed transactionId);
+ event Execution(uint indexed transactionId);
+ event ExecutionFailure(uint indexed transactionId);
+ event OwnerAddition(address indexed owner);
+ event OwnerRemoval(address indexed owner);
+ event RequirementChange(uint required);
+ event TokenBurn(uint256 indexed burnID, address indexed burner, uint256 value, bytes data);
+
+ /*
+ * Constants
+ */
+ uint constant public MAX_OWNER_COUNT = 50;
+ uint public WITHDRAW_FEE = 0;
+ uint public DEPOSIT_FEE = 0;
+
+ /*
+ * Storage
+ */
+ mapping (uint => Transaction) public transactions;
+ mapping (uint => mapping (address => bool)) public confirmations;
+ mapping (address => bool) public isOwner;
+ address[] public owners;
+ uint public required;
+ uint public transactionCount;
+ TokenBurnData[] public burnList;
+
+ struct TokenBurnData {
+ uint256 value;
+ address burner;
+ bytes data;
+ }
+
+ struct Transaction {
+ address destination;
+ uint value;
+ bytes data; //data is used in transactions altering owner list
+ bool executed;
+ }
+
+ /*
+ * Modifiers
+ */
+ modifier onlyWallet() {
+ require(msg.sender == address(this));
+ _;
+ }
+
+ modifier onlyContractIssuer() {
+ require(msg.sender == issuer());
+ _;
+ }
+
+ modifier ownerDoesNotExist(address owner) {
+ require(!isOwner[owner]);
+ _;
+ }
+
+ modifier ownerExists(address owner) {
+ require(isOwner[owner]);
+ _;
+ }
+
+ modifier transactionExists(uint transactionId) {
+ require(transactions[transactionId].destination != 0);
+ _;
+ }
+
+ modifier confirmed(uint transactionId, address owner) {
+ require(confirmations[transactionId][owner]);
+ _;
+ }
+
+ modifier notConfirmed(uint transactionId, address owner) {
+ require(!confirmations[transactionId][owner]);
+ _;
+ }
+
+ modifier notExecuted(uint transactionId) {
+ require(!transactions[transactionId].executed);
+ _;
+ }
+
+ modifier notNull(address _address) {
+ require(_address != 0);
+ _;
+ }
+
+ modifier validRequirement(uint ownerCount, uint _required) {
+ require(ownerCount <= MAX_OWNER_COUNT
+ && _required <= ownerCount
+ && _required != 0
+ && ownerCount != 0);
+ _;
+ }
+
+ /*
+ * Public functions
+ */
+ /// @dev Contract constructor sets initial owners and required number of confirmations.
+ /// @param _owners List of initial owners.
+ /// @param _required Number of required confirmations.
+ constructor (address[] _owners,
+ uint _required, string memory _name,
+ string memory _symbol, uint8 _decimals,
+ uint256 cap, uint256 minFee,
+ uint256 depositFee, uint256 withdrawFee
+ ) TRC21(_name, _symbol, _decimals) public validRequirement(_owners.length, _required) {
+ _mint(msg.sender, cap);
+ _changeIssuer(msg.sender);
+ _changeMinFee(minFee);
+ for (uint i=0; i<_owners.length; i++) {
+ require(!isOwner[_owners[i]] && _owners[i] != 0);
+ isOwner[_owners[i]] = true;
+ }
+ owners = _owners;
+ required = _required;
+ DEPOSIT_FEE = depositFee;
+ WITHDRAW_FEE = withdrawFee;
+ }
+
+ function transferContractIssuer(address newOwner) public onlyContractIssuer {
+ if (newOwner != address(0)) {
+ _changeIssuer(msg.sender);
+ }
+ }
+
+ function setDepositFee(uint256 depositFee) public onlyContractIssuer {
+ DEPOSIT_FEE = depositFee;
+ }
+
+ function setWithdrawFee(uint256 withdrawFee) public onlyContractIssuer {
+ WITHDRAW_FEE = withdrawFee;
+ }
+
+ /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
+ /// @param owner Address of new owner.
+ function addOwner(address owner)
+ public
+ onlyWallet
+ ownerDoesNotExist(owner)
+ notNull(owner)
+ validRequirement(owners.length + 1, required)
+ {
+ isOwner[owner] = true;
+ owners.push(owner);
+ OwnerAddition(owner);
+ }
+
+ /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
+ /// @param owner Address of owner.
+ function removeOwner(address owner)
+ public
+ onlyWallet
+ ownerExists(owner)
+ {
+ isOwner[owner] = false;
+ for (uint i=0; i owners.length)
+ changeRequirement(owners.length);
+ OwnerRemoval(owner);
+ }
+
+ /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
+ /// @param owner Address of owner to be replaced.
+ /// @param newOwner Address of new owner.
+ function replaceOwner(address owner, address newOwner)
+ public
+ onlyWallet
+ ownerExists(owner)
+ ownerDoesNotExist(newOwner)
+ {
+ for (uint i=0; i WITHDRAW_FEE); //avoid spamming
+ super._burn(msg.sender, value);
+ if (WITHDRAW_FEE > 0) {
+ super._mint(issuer(), WITHDRAW_FEE);
+ }
+ uint256 burnValue = value.sub(WITHDRAW_FEE);
+ burnList.push(TokenBurnData({
+ value: burnValue,
+ burner: msg.sender,
+ data: data
+ }));
+ TokenBurn(burnList.length - 1, msg.sender, burnValue, data);
+ }
+
+ /// @dev Allows anyone to execute a confirmed transaction.
+ /// @param transactionId Transaction ID.
+ function executeTransaction(uint transactionId)
+ public
+ ownerExists(msg.sender)
+ confirmed(transactionId, msg.sender)
+ notExecuted(transactionId)
+ {
+ if (isConfirmed(transactionId)) {
+ Transaction storage txn = transactions[transactionId];
+ txn.executed = true;
+
+ // just need multisig for minting - freely burn
+ if (txn.data.length == 0) {
+ //execute minting transaction
+ txn.value = txn.value.sub(DEPOSIT_FEE);
+ super._mint(txn.destination, txn.value);
+ if (DEPOSIT_FEE > 0) {
+ super._mint(issuer(), DEPOSIT_FEE);
+ }
+ Execution(transactionId);
+ } else {
+ //transaction that alters the owners list
+ if (txn.destination.call.value(txn.value)(txn.data))
+ Execution(transactionId);
+ else {
+ ExecutionFailure(transactionId);
+ txn.executed = false;
+ }
+ }
+ }
+ }
+
+ /// @dev Returns the confirmation status of a transaction.
+ /// @param transactionId Transaction ID.
+ /// @return Confirmation status.
+ function isConfirmed(uint transactionId)
+ public
+ constant
+ returns (bool)
+ {
+ uint count = 0;
+ for (uint i=0; i transactionCount? transactionCount: to;
+ uint[] memory transactionIdsTemp = new uint[](end - from);
+ uint count = 0;
+ uint i;
+ for (i = from; i < to; i++) {
+ if ((pending && !transactions[i].executed)
+ || (executed && transactions[i].executed))
+ {
+ transactionIdsTemp[count] = i;
+ count += 1;
+ }
+ }
+ _transactionIds = new uint[](count);
+ for (i = 0; i < count; i++)
+ _transactionIds[i] = transactionIdsTemp[i];
+ }
+
+ function getBurnCount() public view returns (uint256) {
+ return burnList.length;
+ }
+
+ function getBurn(uint burnId) public view returns (address _burner, uint256 _value, bytes _data) {
+ _burner = burnList[burnId].burner;
+ _value = burnList[burnId].value;
+ _data = burnList[burnId].data;
+ }
+
+}
diff --git a/contracts/XDCx/contract/TRC21Issuer.go b/contracts/XDCx/contract/TRC21Issuer.go
new file mode 100644
index 0000000000..72c7f3a2d8
--- /dev/null
+++ b/contracts/XDCx/contract/TRC21Issuer.go
@@ -0,0 +1,767 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "math/big"
+ "strings"
+)
+
+// AbstractTokenTRC21ABI is the input ABI used to generate the binding from.
+const AbstractTokenTRC21ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"issuer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
+
+// AbstractTokenTRC21Bin is the compiled bytecode used for deploying new contracts.
+const AbstractTokenTRC21Bin = `0x`
+
+// DeployAbstractTokenTRC21 deploys a new Ethereum contract, binding an instance of AbstractTokenTRC21 to it.
+func DeployAbstractTokenTRC21(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *AbstractTokenTRC21, error) {
+ parsed, err := abi.JSON(strings.NewReader(AbstractTokenTRC21ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(AbstractTokenTRC21Bin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &AbstractTokenTRC21{AbstractTokenTRC21Caller: AbstractTokenTRC21Caller{contract: contract}, AbstractTokenTRC21Transactor: AbstractTokenTRC21Transactor{contract: contract}, AbstractTokenTRC21Filterer: AbstractTokenTRC21Filterer{contract: contract}}, nil
+}
+
+// AbstractTokenTRC21 is an auto generated Go binding around an Ethereum contract.
+type AbstractTokenTRC21 struct {
+ AbstractTokenTRC21Caller // Read-only binding to the contract
+ AbstractTokenTRC21Transactor // Write-only binding to the contract
+ AbstractTokenTRC21Filterer // Log filterer for contract events
+}
+
+// AbstractTokenTRC21Caller is an auto generated read-only Go binding around an Ethereum contract.
+type AbstractTokenTRC21Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractTokenTRC21Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type AbstractTokenTRC21Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractTokenTRC21Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type AbstractTokenTRC21Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AbstractTokenTRC21Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type AbstractTokenTRC21Session struct {
+ Contract *AbstractTokenTRC21 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// AbstractTokenTRC21CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type AbstractTokenTRC21CallerSession struct {
+ Contract *AbstractTokenTRC21Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// AbstractTokenTRC21TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type AbstractTokenTRC21TransactorSession struct {
+ Contract *AbstractTokenTRC21Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// AbstractTokenTRC21Raw is an auto generated low-level Go binding around an Ethereum contract.
+type AbstractTokenTRC21Raw struct {
+ Contract *AbstractTokenTRC21 // Generic contract binding to access the raw methods on
+}
+
+// AbstractTokenTRC21CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type AbstractTokenTRC21CallerRaw struct {
+ Contract *AbstractTokenTRC21Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// AbstractTokenTRC21TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type AbstractTokenTRC21TransactorRaw struct {
+ Contract *AbstractTokenTRC21Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewAbstractTokenTRC21 creates a new instance of AbstractTokenTRC21, bound to a specific deployed contract.
+func NewAbstractTokenTRC21(address common.Address, backend bind.ContractBackend) (*AbstractTokenTRC21, error) {
+ contract, err := bindAbstractTokenTRC21(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractTokenTRC21{AbstractTokenTRC21Caller: AbstractTokenTRC21Caller{contract: contract}, AbstractTokenTRC21Transactor: AbstractTokenTRC21Transactor{contract: contract}, AbstractTokenTRC21Filterer: AbstractTokenTRC21Filterer{contract: contract}}, nil
+}
+
+// NewAbstractTokenTRC21Caller creates a new read-only instance of AbstractTokenTRC21, bound to a specific deployed contract.
+func NewAbstractTokenTRC21Caller(address common.Address, caller bind.ContractCaller) (*AbstractTokenTRC21Caller, error) {
+ contract, err := bindAbstractTokenTRC21(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractTokenTRC21Caller{contract: contract}, nil
+}
+
+// NewAbstractTokenTRC21Transactor creates a new write-only instance of AbstractTokenTRC21, bound to a specific deployed contract.
+func NewAbstractTokenTRC21Transactor(address common.Address, transactor bind.ContractTransactor) (*AbstractTokenTRC21Transactor, error) {
+ contract, err := bindAbstractTokenTRC21(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractTokenTRC21Transactor{contract: contract}, nil
+}
+
+// NewAbstractTokenTRC21Filterer creates a new log filterer instance of AbstractTokenTRC21, bound to a specific deployed contract.
+func NewAbstractTokenTRC21Filterer(address common.Address, filterer bind.ContractFilterer) (*AbstractTokenTRC21Filterer, error) {
+ contract, err := bindAbstractTokenTRC21(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &AbstractTokenTRC21Filterer{contract: contract}, nil
+}
+
+// bindAbstractTokenTRC21 binds a generic wrapper to an already deployed contract.
+func bindAbstractTokenTRC21(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(AbstractTokenTRC21ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _AbstractTokenTRC21.Contract.AbstractTokenTRC21Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _AbstractTokenTRC21.Contract.AbstractTokenTRC21Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _AbstractTokenTRC21.Contract.AbstractTokenTRC21Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _AbstractTokenTRC21.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _AbstractTokenTRC21.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AbstractTokenTRC21 *AbstractTokenTRC21TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _AbstractTokenTRC21.Contract.contract.Transact(opts, method, params...)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_AbstractTokenTRC21 *AbstractTokenTRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _AbstractTokenTRC21.contract.Call(opts, out, "issuer")
+ return *ret0, err
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_AbstractTokenTRC21 *AbstractTokenTRC21Session) Issuer() (common.Address, error) {
+ return _AbstractTokenTRC21.Contract.Issuer(&_AbstractTokenTRC21.CallOpts)
+}
+
+// Issuer is a free data retrieval call binding the contract method 0x1d143848.
+//
+// Solidity: function issuer() constant returns(address)
+func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerSession) Issuer() (common.Address, error) {
+ return _AbstractTokenTRC21.Contract.Issuer(&_AbstractTokenTRC21.CallOpts)
+}
+
+// TRC21IssuerABI is the input ABI used to generate the binding from.
+const TRC21IssuerABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"minCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenCapacity\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tokens\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"apply\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"charge\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Apply\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"supporter\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Charge\",\"type\":\"event\"}]"
+
+// TRC21IssuerBin is the compiled bytecode used for deploying new contracts.
+const TRC21IssuerBin = `0x608060405234801561001057600080fd5b506040516020806104578339810160405251600055610423806100346000396000f30060806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa615b081146100715780638f3a981c146100985780639d63848a146100b9578063c6b32f341461011e578063fc6bd76a14610134575b600080fd5b34801561007d57600080fd5b50610086610148565b60408051918252519081900360200190f35b3480156100a457600080fd5b50610086600160a060020a036004351661014e565b3480156100c557600080fd5b506100ce610169565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561010a5781810151838201526020016100f2565b505050509050019250505060405180910390f35b610132600160a060020a03600435166101cb565b005b610132600160a060020a036004351661035d565b60005490565b600160a060020a031660009081526002602052604090205490565b606060018054806020026020016040519081016040528092919081815260200182805480156101c157602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116101a3575b5050505050905090565b600081600160a060020a03811615156101e357600080fd5b6000543410156101f257600080fd5b82915033600160a060020a031682600160a060020a0316631d1438486040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050506040513d602081101561028057600080fd5b5051600160a060020a03161461029557600080fd5b600180548082019091557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf601805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03851690811790915560009081526002602052604090205461030390346103de565b600160a060020a0384166000818152600260209081526040918290209390935580513481529051919233927f2d485624158277d5113a56388c3abf5c20e3511dd112123ba376d16b21e4d7169281900390910190a3505050565b600160a060020a038116600090815260026020526040902054610386903463ffffffff6103de16565b600160a060020a0382166000818152600260209081526040918290209390935580513481529051919233927f5cffac866325fd9b2a8ea8df2f110a0058313b279402d15ae28dd324a2282e069281900390910190a350565b6000828201838110156103f057600080fd5b93925050505600a165627a7a7230582005dc9504c7a156980fbaadfe03ffb20a475e65b947f9a8ef3e6d6beee52325a80029`
+
+// DeployTRC21Issuer deploys a new Ethereum contract, binding an instance of TRC21Issuer to it.
+func DeployTRC21Issuer(auth *bind.TransactOpts, backend bind.ContractBackend, value *big.Int) (common.Address, *types.Transaction, *TRC21Issuer, error) {
+ parsed, err := abi.JSON(strings.NewReader(TRC21IssuerABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TRC21IssuerBin), backend, value)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &TRC21Issuer{TRC21IssuerCaller: TRC21IssuerCaller{contract: contract}, TRC21IssuerTransactor: TRC21IssuerTransactor{contract: contract}, TRC21IssuerFilterer: TRC21IssuerFilterer{contract: contract}}, nil
+}
+
+// TRC21Issuer is an auto generated Go binding around an Ethereum contract.
+type TRC21Issuer struct {
+ TRC21IssuerCaller // Read-only binding to the contract
+ TRC21IssuerTransactor // Write-only binding to the contract
+ TRC21IssuerFilterer // Log filterer for contract events
+}
+
+// TRC21IssuerCaller is an auto generated read-only Go binding around an Ethereum contract.
+type TRC21IssuerCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21IssuerTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type TRC21IssuerTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21IssuerFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type TRC21IssuerFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TRC21IssuerSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type TRC21IssuerSession struct {
+ Contract *TRC21Issuer // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// TRC21IssuerCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type TRC21IssuerCallerSession struct {
+ Contract *TRC21IssuerCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// TRC21IssuerTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type TRC21IssuerTransactorSession struct {
+ Contract *TRC21IssuerTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// TRC21IssuerRaw is an auto generated low-level Go binding around an Ethereum contract.
+type TRC21IssuerRaw struct {
+ Contract *TRC21Issuer // Generic contract binding to access the raw methods on
+}
+
+// TRC21IssuerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type TRC21IssuerCallerRaw struct {
+ Contract *TRC21IssuerCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// TRC21IssuerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type TRC21IssuerTransactorRaw struct {
+ Contract *TRC21IssuerTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewTRC21Issuer creates a new instance of TRC21Issuer, bound to a specific deployed contract.
+func NewTRC21Issuer(address common.Address, backend bind.ContractBackend) (*TRC21Issuer, error) {
+ contract, err := bindTRC21Issuer(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21Issuer{TRC21IssuerCaller: TRC21IssuerCaller{contract: contract}, TRC21IssuerTransactor: TRC21IssuerTransactor{contract: contract}, TRC21IssuerFilterer: TRC21IssuerFilterer{contract: contract}}, nil
+}
+
+// NewTRC21IssuerCaller creates a new read-only instance of TRC21Issuer, bound to a specific deployed contract.
+func NewTRC21IssuerCaller(address common.Address, caller bind.ContractCaller) (*TRC21IssuerCaller, error) {
+ contract, err := bindTRC21Issuer(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21IssuerCaller{contract: contract}, nil
+}
+
+// NewTRC21IssuerTransactor creates a new write-only instance of TRC21Issuer, bound to a specific deployed contract.
+func NewTRC21IssuerTransactor(address common.Address, transactor bind.ContractTransactor) (*TRC21IssuerTransactor, error) {
+ contract, err := bindTRC21Issuer(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21IssuerTransactor{contract: contract}, nil
+}
+
+// NewTRC21IssuerFilterer creates a new log filterer instance of TRC21Issuer, bound to a specific deployed contract.
+func NewTRC21IssuerFilterer(address common.Address, filterer bind.ContractFilterer) (*TRC21IssuerFilterer, error) {
+ contract, err := bindTRC21Issuer(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21IssuerFilterer{contract: contract}, nil
+}
+
+// bindTRC21Issuer binds a generic wrapper to an already deployed contract.
+func bindTRC21Issuer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(TRC21IssuerABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_TRC21Issuer *TRC21IssuerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _TRC21Issuer.Contract.TRC21IssuerCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_TRC21Issuer *TRC21IssuerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.TRC21IssuerTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TRC21Issuer *TRC21IssuerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.TRC21IssuerTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_TRC21Issuer *TRC21IssuerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _TRC21Issuer.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_TRC21Issuer *TRC21IssuerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TRC21Issuer *TRC21IssuerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.contract.Transact(opts, method, params...)
+}
+
+// GetTokenCapacity is a free data retrieval call binding the contract method 0x8f3a981c.
+//
+// Solidity: function getTokenCapacity(token address) constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerCaller) GetTokenCapacity(opts *bind.CallOpts, token common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21Issuer.contract.Call(opts, out, "getTokenCapacity", token)
+ return *ret0, err
+}
+
+// GetTokenCapacity is a free data retrieval call binding the contract method 0x8f3a981c.
+//
+// Solidity: function getTokenCapacity(token address) constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerSession) GetTokenCapacity(token common.Address) (*big.Int, error) {
+ return _TRC21Issuer.Contract.GetTokenCapacity(&_TRC21Issuer.CallOpts, token)
+}
+
+// GetTokenCapacity is a free data retrieval call binding the contract method 0x8f3a981c.
+//
+// Solidity: function getTokenCapacity(token address) constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerCallerSession) GetTokenCapacity(token common.Address) (*big.Int, error) {
+ return _TRC21Issuer.Contract.GetTokenCapacity(&_TRC21Issuer.CallOpts, token)
+}
+
+// MinCap is a free data retrieval call binding the contract method 0x3fa615b0.
+//
+// Solidity: function minCap() constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerCaller) MinCap(opts *bind.CallOpts) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _TRC21Issuer.contract.Call(opts, out, "minCap")
+ return *ret0, err
+}
+
+// MinCap is a free data retrieval call binding the contract method 0x3fa615b0.
+//
+// Solidity: function minCap() constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerSession) MinCap() (*big.Int, error) {
+ return _TRC21Issuer.Contract.MinCap(&_TRC21Issuer.CallOpts)
+}
+
+// MinCap is a free data retrieval call binding the contract method 0x3fa615b0.
+//
+// Solidity: function minCap() constant returns(uint256)
+func (_TRC21Issuer *TRC21IssuerCallerSession) MinCap() (*big.Int, error) {
+ return _TRC21Issuer.Contract.MinCap(&_TRC21Issuer.CallOpts)
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_TRC21Issuer *TRC21IssuerCaller) Tokens(opts *bind.CallOpts) ([]common.Address, error) {
+ var (
+ ret0 = new([]common.Address)
+ )
+ out := ret0
+ err := _TRC21Issuer.contract.Call(opts, out, "tokens")
+ return *ret0, err
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_TRC21Issuer *TRC21IssuerSession) Tokens() ([]common.Address, error) {
+ return _TRC21Issuer.Contract.Tokens(&_TRC21Issuer.CallOpts)
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_TRC21Issuer *TRC21IssuerCallerSession) Tokens() ([]common.Address, error) {
+ return _TRC21Issuer.Contract.Tokens(&_TRC21Issuer.CallOpts)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_TRC21Issuer *TRC21IssuerTransactor) Apply(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.contract.Transact(opts, "apply", token)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_TRC21Issuer *TRC21IssuerSession) Apply(token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.Apply(&_TRC21Issuer.TransactOpts, token)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_TRC21Issuer *TRC21IssuerTransactorSession) Apply(token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.Apply(&_TRC21Issuer.TransactOpts, token)
+}
+
+// Charge is a paid mutator transaction binding the contract method 0xfc6bd76a.
+//
+// Solidity: function charge(token address) returns()
+func (_TRC21Issuer *TRC21IssuerTransactor) Charge(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.contract.Transact(opts, "charge", token)
+}
+
+// Charge is a paid mutator transaction binding the contract method 0xfc6bd76a.
+//
+// Solidity: function charge(token address) returns()
+func (_TRC21Issuer *TRC21IssuerSession) Charge(token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.Charge(&_TRC21Issuer.TransactOpts, token)
+}
+
+// Charge is a paid mutator transaction binding the contract method 0xfc6bd76a.
+//
+// Solidity: function charge(token address) returns()
+func (_TRC21Issuer *TRC21IssuerTransactorSession) Charge(token common.Address) (*types.Transaction, error) {
+ return _TRC21Issuer.Contract.Charge(&_TRC21Issuer.TransactOpts, token)
+}
+
+// TRC21IssuerApplyIterator is returned from FilterApply and is used to iterate over the raw logs and unpacked data for Apply events raised by the TRC21Issuer contract.
+type TRC21IssuerApplyIterator struct {
+ Event *TRC21IssuerApply // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub XDPoSChain.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *TRC21IssuerApplyIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21IssuerApply)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21IssuerApply)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *TRC21IssuerApplyIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TRC21IssuerApplyIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TRC21IssuerApply represents a Apply event raised by the TRC21Issuer contract.
+type TRC21IssuerApply struct {
+ Issuer common.Address
+ Token common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterApply is a free log retrieval operation binding the contract event 0x2d485624158277d5113a56388c3abf5c20e3511dd112123ba376d16b21e4d716.
+//
+// Solidity: event Apply(issuer indexed address, token indexed address, value uint256)
+func (_TRC21Issuer *TRC21IssuerFilterer) FilterApply(opts *bind.FilterOpts, issuer []common.Address, token []common.Address) (*TRC21IssuerApplyIterator, error) {
+
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+ var tokenRule []interface{}
+ for _, tokenItem := range token {
+ tokenRule = append(tokenRule, tokenItem)
+ }
+
+ logs, sub, err := _TRC21Issuer.contract.FilterLogs(opts, "Apply", issuerRule, tokenRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21IssuerApplyIterator{contract: _TRC21Issuer.contract, event: "Apply", logs: logs, sub: sub}, nil
+}
+
+// WatchApply is a free log subscription operation binding the contract event 0x2d485624158277d5113a56388c3abf5c20e3511dd112123ba376d16b21e4d716.
+//
+// Solidity: event Apply(issuer indexed address, token indexed address, value uint256)
+func (_TRC21Issuer *TRC21IssuerFilterer) WatchApply(opts *bind.WatchOpts, sink chan<- *TRC21IssuerApply, issuer []common.Address, token []common.Address) (event.Subscription, error) {
+
+ var issuerRule []interface{}
+ for _, issuerItem := range issuer {
+ issuerRule = append(issuerRule, issuerItem)
+ }
+ var tokenRule []interface{}
+ for _, tokenItem := range token {
+ tokenRule = append(tokenRule, tokenItem)
+ }
+
+ logs, sub, err := _TRC21Issuer.contract.WatchLogs(opts, "Apply", issuerRule, tokenRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(TRC21IssuerApply)
+ if err := _TRC21Issuer.contract.UnpackLog(event, "Apply", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// TRC21IssuerChargeIterator is returned from FilterCharge and is used to iterate over the raw logs and unpacked data for Charge events raised by the TRC21Issuer contract.
+type TRC21IssuerChargeIterator struct {
+ Event *TRC21IssuerCharge // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub XDPoSChain.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *TRC21IssuerChargeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21IssuerCharge)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(TRC21IssuerCharge)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *TRC21IssuerChargeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TRC21IssuerChargeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TRC21IssuerCharge represents a Charge event raised by the TRC21Issuer contract.
+type TRC21IssuerCharge struct {
+ Supporter common.Address
+ Token common.Address
+ Value *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterCharge is a free log retrieval operation binding the contract event 0x5cffac866325fd9b2a8ea8df2f110a0058313b279402d15ae28dd324a2282e06.
+//
+// Solidity: event Charge(supporter indexed address, token indexed address, value uint256)
+func (_TRC21Issuer *TRC21IssuerFilterer) FilterCharge(opts *bind.FilterOpts, supporter []common.Address, token []common.Address) (*TRC21IssuerChargeIterator, error) {
+
+ var supporterRule []interface{}
+ for _, supporterItem := range supporter {
+ supporterRule = append(supporterRule, supporterItem)
+ }
+ var tokenRule []interface{}
+ for _, tokenItem := range token {
+ tokenRule = append(tokenRule, tokenItem)
+ }
+
+ logs, sub, err := _TRC21Issuer.contract.FilterLogs(opts, "Charge", supporterRule, tokenRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TRC21IssuerChargeIterator{contract: _TRC21Issuer.contract, event: "Charge", logs: logs, sub: sub}, nil
+}
+
+// WatchCharge is a free log subscription operation binding the contract event 0x5cffac866325fd9b2a8ea8df2f110a0058313b279402d15ae28dd324a2282e06.
+//
+// Solidity: event Charge(supporter indexed address, token indexed address, value uint256)
+func (_TRC21Issuer *TRC21IssuerFilterer) WatchCharge(opts *bind.WatchOpts, sink chan<- *TRC21IssuerCharge, supporter []common.Address, token []common.Address) (event.Subscription, error) {
+
+ var supporterRule []interface{}
+ for _, supporterItem := range supporter {
+ supporterRule = append(supporterRule, supporterItem)
+ }
+ var tokenRule []interface{}
+ for _, tokenItem := range token {
+ tokenRule = append(tokenRule, tokenItem)
+ }
+
+ logs, sub, err := _TRC21Issuer.contract.WatchLogs(opts, "Charge", supporterRule, tokenRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(TRC21IssuerCharge)
+ if err := _TRC21Issuer.contract.UnpackLog(event, "Charge", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/contracts/XDCx/contract/TRC21Issuer.sol b/contracts/XDCx/contract/TRC21Issuer.sol
new file mode 100644
index 0000000000..6825df722a
--- /dev/null
+++ b/contracts/XDCx/contract/TRC21Issuer.sol
@@ -0,0 +1,111 @@
+pragma solidity ^0.4.24;
+
+library SafeMath {
+
+ /**
+ * @dev Multiplies two numbers, reverts on overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b);
+
+ return c;
+ }
+
+ /**
+ * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b > 0); // Solidity only automatically asserts when dividing by 0
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b <= a);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Adds two numbers, reverts on overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a);
+
+ return c;
+ }
+
+ /**
+ * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
+ * reverts when dividing by zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ require(b != 0);
+ return a % b;
+ }
+}
+
+contract AbstractTokenTRC21 {
+ function issuer() public view returns (address);
+}
+
+contract TRC21Issuer {
+ using SafeMath for uint256;
+ uint256 _minCap;
+ address[] _tokens;
+ mapping(address => uint256) tokensState;
+
+ event Apply(address indexed issuer, address indexed token, uint256 value);
+ event Charge(address indexed supporter, address indexed token, uint256 value);
+
+ constructor (uint256 value) public {
+ _minCap = value;
+ }
+
+ function minCap() public view returns(uint256) {
+ return _minCap;
+ }
+
+ function tokens() public view returns(address[]) {
+ return _tokens;
+ }
+
+ function getTokenCapacity(address token) public view returns(uint256) {
+ return tokensState[token];
+ }
+
+ modifier onlyValidCapacity(address token) {
+ require(token != address(0));
+ require(msg.value >= _minCap);
+ _;
+ }
+
+ function apply(address token) public payable onlyValidCapacity(token) {
+ AbstractTokenTRC21 t = AbstractTokenTRC21(token);
+ require(t.issuer() == msg.sender);
+ _tokens.push(token);
+ tokensState[token] = tokensState[token].add(msg.value);
+ emit Apply(msg.sender, token, msg.value);
+ }
+
+ function charge(address token) public payable {
+ tokensState[token] = tokensState[token].add(msg.value);
+ emit Charge(msg.sender, token, msg.value);
+ }
+
+}
diff --git a/contracts/XDCx/contract/XDCXListing.go b/contracts/XDCx/contract/XDCXListing.go
new file mode 100644
index 0000000000..1b017c7b01
--- /dev/null
+++ b/contracts/XDCx/contract/XDCXListing.go
@@ -0,0 +1,247 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "strings"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+)
+
+// XDCXListingABI is the input ABI used to generate the binding from.
+const XDCXListingABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"tokens\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"apply\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"}]"
+
+// XDCXListingBin is the compiled bytecode used for deploying new contracts.
+const XDCXListingBin = `0x608060405234801561001057600080fd5b506102be806100206000396000f3006080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416639d63848a811461005b578063a3ff31b5146100c0578063c6b32f34146100f5575b600080fd5b34801561006757600080fd5b5061007061010b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156100ac578181015183820152602001610094565b505050509050019250505060405180910390f35b3480156100cc57600080fd5b506100e1600160a060020a036004351661016d565b604080519115158252519081900360200190f35b610109600160a060020a036004351661018b565b005b6060600080548060200260200160405190810160405280929190818152602001828054801561016357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610145575b5050505050905090565b600160a060020a031660009081526001602052604090205460ff1690565b80600160a060020a03811615156101a157600080fd5b600160a060020a03811660009081526001602081905260409091205460ff16151514156101cd57600080fd5b683635c9adc5dea0000034146101e257600080fd5b6040516068903480156108fc02916000818181858888f1935050505015801561020f573d6000803e3d6000fd5b505060008054600180820183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563909101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039490941693841790556040805160208082018352838252948452919093529190209051815460ff19169015151790555600a165627a7a723058206d2dc0ce827743c25efa82f99e7830ade39d28e17f4d651573f89e0460a6626a0029`
+
+// DeployXDCXListing deploys a new Ethereum contract, binding an instance of XDCXListing to it.
+func DeployXDCXListing(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *XDCXListing, error) {
+ parsed, err := abi.JSON(strings.NewReader(XDCXListingABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(XDCXListingBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &XDCXListing{XDCXListingCaller: XDCXListingCaller{contract: contract}, XDCXListingTransactor: XDCXListingTransactor{contract: contract}, XDCXListingFilterer: XDCXListingFilterer{contract: contract}}, nil
+}
+
+// XDCXListing is an auto generated Go binding around an Ethereum contract.
+type XDCXListing struct {
+ XDCXListingCaller // Read-only binding to the contract
+ XDCXListingTransactor // Write-only binding to the contract
+ XDCXListingFilterer // Log filterer for contract events
+}
+
+// XDCXListingCaller is an auto generated read-only Go binding around an Ethereum contract.
+type XDCXListingCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// XDCXListingTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type XDCXListingTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// XDCXListingFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type XDCXListingFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// XDCXListingSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type XDCXListingSession struct {
+ Contract *XDCXListing // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// XDCXListingCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type XDCXListingCallerSession struct {
+ Contract *XDCXListingCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// XDCXListingTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type XDCXListingTransactorSession struct {
+ Contract *XDCXListingTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// XDCXListingRaw is an auto generated low-level Go binding around an Ethereum contract.
+type XDCXListingRaw struct {
+ Contract *XDCXListing // Generic contract binding to access the raw methods on
+}
+
+// XDCXListingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type XDCXListingCallerRaw struct {
+ Contract *XDCXListingCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// XDCXListingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type XDCXListingTransactorRaw struct {
+ Contract *XDCXListingTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewXDCXListing creates a new instance of XDCXListing, bound to a specific deployed contract.
+func NewXDCXListing(address common.Address, backend bind.ContractBackend) (*XDCXListing, error) {
+ contract, err := bindXDCXListing(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &XDCXListing{XDCXListingCaller: XDCXListingCaller{contract: contract}, XDCXListingTransactor: XDCXListingTransactor{contract: contract}, XDCXListingFilterer: XDCXListingFilterer{contract: contract}}, nil
+}
+
+// NewXDCXListingCaller creates a new read-only instance of XDCXListing, bound to a specific deployed contract.
+func NewXDCXListingCaller(address common.Address, caller bind.ContractCaller) (*XDCXListingCaller, error) {
+ contract, err := bindXDCXListing(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &XDCXListingCaller{contract: contract}, nil
+}
+
+// NewXDCXListingTransactor creates a new write-only instance of XDCXListing, bound to a specific deployed contract.
+func NewXDCXListingTransactor(address common.Address, transactor bind.ContractTransactor) (*XDCXListingTransactor, error) {
+ contract, err := bindXDCXListing(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &XDCXListingTransactor{contract: contract}, nil
+}
+
+// NewXDCXListingFilterer creates a new log filterer instance of XDCXListing, bound to a specific deployed contract.
+func NewXDCXListingFilterer(address common.Address, filterer bind.ContractFilterer) (*XDCXListingFilterer, error) {
+ contract, err := bindXDCXListing(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &XDCXListingFilterer{contract: contract}, nil
+}
+
+// bindXDCXListing binds a generic wrapper to an already deployed contract.
+func bindXDCXListing(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(XDCXListingABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_XDCXListing *XDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _XDCXListing.Contract.XDCXListingCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_XDCXListing *XDCXListingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _XDCXListing.Contract.XDCXListingTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_XDCXListing *XDCXListingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _XDCXListing.Contract.XDCXListingTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_XDCXListing *XDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _XDCXListing.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_XDCXListing *XDCXListingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _XDCXListing.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_XDCXListing *XDCXListingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _XDCXListing.Contract.contract.Transact(opts, method, params...)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus(token address) constant returns(bool)
+func (_XDCXListing *XDCXListingCaller) GetTokenStatus(opts *bind.CallOpts, token common.Address) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _XDCXListing.contract.Call(opts, out, "getTokenStatus", token)
+ return *ret0, err
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus(token address) constant returns(bool)
+func (_XDCXListing *XDCXListingSession) GetTokenStatus(token common.Address) (bool, error) {
+ return _XDCXListing.Contract.GetTokenStatus(&_XDCXListing.CallOpts, token)
+}
+
+// GetTokenStatus is a free data retrieval call binding the contract method 0xa3ff31b5.
+//
+// Solidity: function getTokenStatus(token address) constant returns(bool)
+func (_XDCXListing *XDCXListingCallerSession) GetTokenStatus(token common.Address) (bool, error) {
+ return _XDCXListing.Contract.GetTokenStatus(&_XDCXListing.CallOpts, token)
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_XDCXListing *XDCXListingCaller) Tokens(opts *bind.CallOpts) ([]common.Address, error) {
+ var (
+ ret0 = new([]common.Address)
+ )
+ out := ret0
+ err := _XDCXListing.contract.Call(opts, out, "tokens")
+ return *ret0, err
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_XDCXListing *XDCXListingSession) Tokens() ([]common.Address, error) {
+ return _XDCXListing.Contract.Tokens(&_XDCXListing.CallOpts)
+}
+
+// Tokens is a free data retrieval call binding the contract method 0x9d63848a.
+//
+// Solidity: function tokens() constant returns(address[])
+func (_XDCXListing *XDCXListingCallerSession) Tokens() ([]common.Address, error) {
+ return _XDCXListing.Contract.Tokens(&_XDCXListing.CallOpts)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_XDCXListing *XDCXListingTransactor) Apply(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) {
+ return _XDCXListing.contract.Transact(opts, "apply", token)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_XDCXListing *XDCXListingSession) Apply(token common.Address) (*types.Transaction, error) {
+ return _XDCXListing.Contract.Apply(&_XDCXListing.TransactOpts, token)
+}
+
+// Apply is a paid mutator transaction binding the contract method 0xc6b32f34.
+//
+// Solidity: function apply(token address) returns()
+func (_XDCXListing *XDCXListingTransactorSession) Apply(token common.Address) (*types.Transaction, error) {
+ return _XDCXListing.Contract.Apply(&_XDCXListing.TransactOpts, token)
+}
diff --git a/contracts/XDCx/contract/XDCXListing.sol b/contracts/XDCx/contract/XDCXListing.sol
new file mode 100644
index 0000000000..d4f3b1b906
--- /dev/null
+++ b/contracts/XDCx/contract/XDCXListing.sol
@@ -0,0 +1,36 @@
+pragma solidity ^0.4.24;
+
+contract XDCXListing {
+
+ address[] _tokens;
+ mapping(address => TokenState) tokensState;
+ address constant private foundation = 0x0000000000000000000000000000000000000068;
+
+ struct TokenState {
+ bool isActive;
+ }
+
+ modifier onlyValidApplyNewToken(address token){
+ require(token != address(0));
+ require(tokensState[token].isActive != true);
+ _;
+ }
+
+ function tokens() public view returns(address[]) {
+ return _tokens;
+ }
+
+ function getTokenStatus(address token) public view returns(bool) {
+ return tokensState[token].isActive;
+ }
+
+ function apply(address token) public payable onlyValidApplyNewToken(token){
+ require(msg.value == 1000 ether);
+ foundation.transfer(msg.value);
+
+ _tokens.push(token);
+ tokensState[token] = TokenState({
+ isActive: true
+ });
+ }
+}
diff --git a/contracts/XDCx/contract/XDCXPrice.sol b/contracts/XDCx/contract/XDCXPrice.sol
new file mode 100644
index 0000000000..66ac51c11e
--- /dev/null
+++ b/contracts/XDCx/contract/XDCXPrice.sol
@@ -0,0 +1,35 @@
+pragma solidity 0.4.24;
+
+contract XDCXPrice {
+ function GetLastPrice(address base, address quote) public view returns(uint256) {
+ address XDCX_LAST_PRICE_PRECOMPILED_CONTRACT = 0x0000000000000000000000000000000000000029;
+ uint256[1] memory result;
+ address[2] memory input;
+ input[0] = base;
+ input[1] = quote;
+ assembly {
+ // GetLastPrice precompile!
+ if iszero(staticcall(not(0), XDCX_LAST_PRICE_PRECOMPILED_CONTRACT, input, 0x40, result, 0x20)) {
+ revert(0, 0)
+ }
+ }
+ return result[0];
+ }
+
+ function GetEpochPrice(address base, address quote) public view returns(uint256) {
+ address XDCX_EPOCH_PRICE_PRECOMPILED_CONTRACT = 0x000000000000000000000000000000000000002A;
+ uint256[1] memory result;
+ address[2] memory input;
+ input[0] = base;
+ input[1] = quote;
+ assembly {
+ // GetEpochPrice precompile!
+ if iszero(staticcall(not(0), XDCX_EPOCH_PRICE_PRECOMPILED_CONTRACT, input, 0x40, result, 0x20)) {
+ revert(0, 0)
+ }
+ }
+ return result[0];
+ }
+}
+
+
diff --git a/contracts/XDCx/lendingRelayerRegistration.go b/contracts/XDCx/lendingRelayerRegistration.go
new file mode 100644
index 0000000000..8880ca2808
--- /dev/null
+++ b/contracts/XDCx/lendingRelayerRegistration.go
@@ -0,0 +1,40 @@
+package XDCx
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+)
+
+type LendingRelayerRegistration struct {
+ *contract.LendingSession
+ contractBackend bind.ContractBackend
+}
+
+func NewLendingRelayerRegistration(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*LendingRelayerRegistration, error) {
+ smartContract, err := contract.NewLending(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &LendingRelayerRegistration{
+ &contract.LendingSession{
+ Contract: smartContract,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployLendingRelayerRegistration(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, relayerAddr common.Address, XDCxListtingAddr common.Address) (common.Address, *LendingRelayerRegistration, error) {
+ contractAddr, _, _, err := contract.DeployLending(transactOpts, contractBackend, relayerAddr, XDCxListtingAddr)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ smartContract, err := NewLendingRelayerRegistration(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, smartContract, nil
+}
diff --git a/contracts/XDCx/relayerRegistration.go b/contracts/XDCx/relayerRegistration.go
new file mode 100644
index 0000000000..343515e02b
--- /dev/null
+++ b/contracts/XDCx/relayerRegistration.go
@@ -0,0 +1,42 @@
+package XDCx
+
+import (
+ "math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+)
+
+type RelayerRegistration struct {
+ *contract.RelayerRegistrationSession
+ contractBackend bind.ContractBackend
+}
+
+func NewRelayerRegistration(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*RelayerRegistration, error) {
+ smartContract, err := contract.NewRelayerRegistration(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &RelayerRegistration{
+ &contract.RelayerRegistrationSession{
+ Contract: smartContract,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployRelayerRegistration(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, XDCxListing common.Address, maxRelayers *big.Int, maxTokenList *big.Int, minDeposit *big.Int) (common.Address, *RelayerRegistration, error) {
+ contractAddr, _, _, err := contract.DeployRelayerRegistration(transactOpts, contractBackend, XDCxListing, maxRelayers, maxTokenList, minDeposit)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ smartContract, err := NewRelayerRegistration(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, smartContract, nil
+}
diff --git a/contracts/XDCx/simulation/constants.go b/contracts/XDCx/simulation/constants.go
new file mode 100644
index 0000000000..b4a3f2b7fe
--- /dev/null
+++ b/contracts/XDCx/simulation/constants.go
@@ -0,0 +1,75 @@
+package simulation
+
+import (
+ "math/big"
+ "os"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+)
+
+var (
+ BaseXDC = big.NewInt(0).Mul(big.NewInt(10), big.NewInt(100000000000000000)) // 1 XDC
+ RpcEndpoint = "http://127.0.0.1:8501/"
+ MainKey, _ = crypto.HexToECDSA(os.Getenv("MAIN_ADDRESS_KEY"))
+ MainAddr = crypto.PubkeyToAddress(MainKey.PublicKey) //0x17F2beD710ba50Ed27aEa52fc4bD7Bda5ED4a037
+
+ // TRC21 Token
+ MinTRC21Apply = big.NewInt(0).Mul(big.NewInt(10), BaseXDC) // 10 XDC
+ TRC21TokenCap = big.NewInt(0).Mul(big.NewInt(1000000000000), BaseXDC)
+ TRC21TokenFee = big.NewInt(0)
+ XDCXListingFee = big.NewInt(0).Mul(big.NewInt(1000), BaseXDC) // 1000 XDC
+
+ // XDCX
+ MaxRelayers = big.NewInt(200)
+ MaxTokenList = big.NewInt(200)
+ MinDeposit = big.NewInt(0).Mul(big.NewInt(25000), BaseXDC) // 25000 XDC
+ CollateralDepositRate = big.NewInt(150)
+ CollateralLiquidationRate = big.NewInt(110)
+ CollateralRecallRate = big.NewInt(200)
+ TradeFee = uint16(10) // trade fee decimals 10^4
+ LendingTradeFee = uint16(100) // lending trade fee decimals 10^4
+ // 1m , 1d,7d,30d
+ Terms = []*big.Int{big.NewInt(60), big.NewInt(86400), big.NewInt(7 * 86400), big.NewInt(30 * 86400)}
+ RelayerCoinbaseKey, _ = crypto.HexToECDSA(os.Getenv("RELAYER_COINBASE_KEY")) //
+ RelayerCoinbaseAddr = crypto.PubkeyToAddress(RelayerCoinbaseKey.PublicKey) // 0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
+
+ OwnerRelayerKey, _ = crypto.HexToECDSA(os.Getenv("RELAYER_OWNER_KEY"))
+ OwnerRelayerAddr = crypto.PubkeyToAddress(OwnerRelayerKey.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
+
+ XDCNative = common.HexToAddress("0x0000000000000000000000000000000000000001")
+
+ TokenNameList = []string{"BTC", "ETH", "XRP", "LTC", "BNB", "ADA", "ETC", "BCH", "EOS", "USDT"}
+ TeamAddresses = []common.Address{
+ common.HexToAddress("0x8fB1047e874d2e472cd08980FF8383053dd83102"), // MM team
+ common.HexToAddress("0x9ca1514E3Dc4059C29a1608AE3a3E3fd35900888"), // MM team
+ common.HexToAddress("0x15e08dE16f534c890828F2a0D935433aF5B3CE0C"), // CTO
+ common.HexToAddress("0xb68D825655F2fE14C32558cDf950b45beF18D218"), // DEX team
+ common.HexToAddress("0xF7349C253FF7747Df661296E0859c44e974fb52E"), // HaiDV
+ common.HexToAddress("0x9f6b8fDD3733B099A91B6D70CDC7963ebBbd2684"), // Can
+ common.HexToAddress("0x06605B28aab9835be75ca242a8aE58f2e15F2F45"), // Nien
+ common.HexToAddress("0x33c2E732ae7dce8B05F37B2ba0CFe14c980c4Dbe"), // Vu Pham
+ common.HexToAddress("0x16a73f3a64eca79e117258e66dfd7071cc8312a9"), // BTCXDC
+ common.HexToAddress("0xac177441ac2237b2f79ecff1b8f6bca39e27ef9f"), // ETHXDC
+ common.HexToAddress("0x4215250e55984c75bbce8ae639b86a6cad8ec126"), // XRPXDC
+ common.HexToAddress("0x6b70ca959814866dd5c426d63d47dde9cc6c32d2"), // LTCXDC
+ common.HexToAddress("0x33df079fe9b9cd7fb23a1085e4eaaa8eb6952cb3"), // BNBXDC
+ common.HexToAddress("0x3cab8292137804688714670640d19f9d7a60c472"), // ADAXDC
+ common.HexToAddress("0x9415d953d47c5f155cac9de7b24a756f352eafbf"), // ETCXDC
+ common.HexToAddress("0xe32d2e7c8e8809e45c8e2332830b48d9e231e3f2"), // BCHXDC
+ common.HexToAddress("0xf76ddbda664ea47088937e1cf9ff15036714dee3"), // EOSXDC
+ common.HexToAddress("0xc465ee82440dada9509feb235c7cd7d896acf13c"), // ETHBTC
+ common.HexToAddress("0xb95bdc136c579dc3fd2b2424a8e925a90228d2c2"), // XRPBTC
+ common.HexToAddress("0xe36c1842365595D44854eEcd64B11c8115E133EF"), // USDXDC
+ common.HexToAddress("0xaaC1959F6F0fb539F653409079Ec4146267B7555"), // BTCUSD
+ common.HexToAddress("0x726DA688e2e09f01A2e1aB4c10F25B7CEdD4a0f3"), // ETHUSD
+ common.HexToAddress("0xc70f010E8DB8bc436712A93D170C7c27Db1981Ea"), // rosetta-cli testing account
+ }
+
+ Required = big.NewInt(2)
+ Owners = []common.Address{
+ common.HexToAddress("0x244e17B2141288a6F00E79E8feC2341f827d156f"),
+ common.HexToAddress("0xd106159eC58BD2EAf5B62eF4e9cDb286170B0Bb9"),
+ common.HexToAddress("0x0197BE034Bf0Bd2b3adDC84366a5681Bb7545888"),
+ }
+)
diff --git a/contracts/XDCx/simulation/deploy/main.go b/contracts/XDCx/simulation/deploy/main.go
new file mode 100644
index 0000000000..379f358674
--- /dev/null
+++ b/contracts/XDCx/simulation/deploy/main.go
@@ -0,0 +1,423 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "math/big"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/simulation"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+)
+
+func main() {
+ fmt.Println("========================")
+ fmt.Println("mainAddr", simulation.MainAddr.Hex())
+ fmt.Println("relayerAddr", simulation.RelayerCoinbaseAddr.Hex())
+ fmt.Println("ownerRelayerAddr", simulation.OwnerRelayerAddr.Hex())
+ fmt.Println("========================")
+ client, err := ethclient.Dial(simulation.RpcEndpoint)
+ if err != nil {
+ fmt.Println(err, client)
+ }
+ nonce, _ := client.NonceAt(context.Background(), simulation.MainAddr, nil)
+ auth := bind.NewKeyedTransactor(simulation.MainKey)
+ auth.Value = big.NewInt(0) // in wei
+ auth.GasLimit = uint64(10000000) // in units
+ auth.GasPrice = big.NewInt(250000000000000)
+
+ // init trc21 issuer
+ auth.Nonce = big.NewInt(int64(nonce))
+ trc21IssuerAddr, trc21Issuer, err := XDCx.DeployTRC21Issuer(auth, client, simulation.MinTRC21Apply)
+ if err != nil {
+ log.Fatal("DeployTRC21Issuer", err)
+ }
+ trc21Issuer.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> trc21 issuer address", trc21IssuerAddr.Hex())
+ fmt.Println("wait 10s to execute init smart contract : TRC Issuer")
+ time.Sleep(2 * time.Second)
+
+ //init XDCX Listing in
+ auth.Nonce = big.NewInt(int64(nonce + 1))
+ XDCxListtingAddr, XDCxListing, err := XDCx.DeployXDCXListing(auth, client)
+ if err != nil {
+ log.Fatal("DeployXDCXListing", err)
+ }
+ XDCxListing.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> XDCx listing address", XDCxListtingAddr.Hex())
+ fmt.Println("wait 10s to execute init smart contract : XDCx listing ")
+ time.Sleep(2 * time.Second)
+
+ // init Relayer Registration
+ auth.Nonce = big.NewInt(int64(nonce + 2))
+ relayerRegistrationAddr, relayerRegistration, err := XDCx.DeployRelayerRegistration(auth, client, XDCxListtingAddr, simulation.MaxRelayers, simulation.MaxTokenList, simulation.MinDeposit)
+ if err != nil {
+ log.Fatal("DeployRelayerRegistration", err)
+ }
+ relayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> relayer registration address", relayerRegistrationAddr.Hex())
+ fmt.Println("wait 2s to execute init smart contract : relayer registration ")
+ time.Sleep(2 * time.Second)
+
+ auth.Nonce = big.NewInt(int64(nonce + 3))
+ lendingRelayerRegistrationAddr, lendingRelayerRegistration, err := XDCx.DeployLendingRelayerRegistration(auth, client, relayerRegistrationAddr, XDCxListtingAddr)
+ if err != nil {
+ log.Fatal("DeployLendingRelayerRegistration", err)
+ }
+ lendingRelayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> lending relayer registration address", lendingRelayerRegistrationAddr.Hex())
+ fmt.Println("wait 2s to execute init smart contract : lending relayer registration ")
+ time.Sleep(2 * time.Second)
+
+ currentNonce := nonce + 4
+ tokenList := initTRC21(auth, client, currentNonce, simulation.TokenNameList)
+
+ currentNonce = currentNonce + uint64(len(simulation.TokenNameList)) // init smartcontract
+
+ applyIssuer(trc21Issuer, tokenList, currentNonce)
+
+ currentNonce = currentNonce + uint64(len(simulation.TokenNameList))
+ applyXDCXListing(XDCxListing, tokenList, currentNonce)
+
+ // BTC Collateral
+ nonce = currentNonce + uint64(len(simulation.TokenNameList))
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(tokenList[0]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // ETH Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(tokenList[1]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // XDC Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(simulation.XDCNative, simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // XRP ILO Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddILOCollateral(tokenList[2]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add ILO collateral", err)
+ }
+
+ // USD lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(tokenList[9]["address"].(common.Address))
+ if err != nil {
+ log.Fatal("Lending add base token USD", err)
+ }
+
+ // XDC lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(simulation.XDCNative)
+ if err != nil {
+ log.Fatal("Lending add base token XDC", err)
+ }
+
+ // BTC lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(tokenList[0]["address"].(common.Address))
+ if err != nil {
+ log.Fatal("Lending add base token BTC", err)
+ }
+
+ // add term 1 minute for testing
+ for i := 0; i < len(simulation.Terms); i++ {
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddTerm(simulation.Terms[i])
+ if err != nil {
+ log.Fatal("Lending add terms", err)
+ }
+ fmt.Println("wait 2s to add term lending lending contract", simulation.Terms[i])
+ time.Sleep(2 * time.Second)
+ }
+ fmt.Println("wait 2s to setup lending contract")
+ time.Sleep(2 * time.Second)
+
+ currentNonce = nonce + 1
+ airdrop(auth, client, tokenList, simulation.TeamAddresses, currentNonce)
+
+ // relayer registration
+ ownerRelayer := bind.NewKeyedTransactor(simulation.OwnerRelayerKey)
+ nonce, _ = client.NonceAt(context.Background(), simulation.OwnerRelayerAddr, nil)
+ relayerRegistration, err = XDCx.NewRelayerRegistration(ownerRelayer, relayerRegistrationAddr, client)
+ if err != nil {
+ log.Fatal("NewRelayerRegistration", err)
+ }
+ relayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ relayerRegistration.TransactOpts.Value = simulation.MinDeposit
+ relayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fromTokens := []common.Address{}
+ toTokens := []common.Address{}
+
+ /*
+ for _, token := range tokenList {
+ fromTokens = append(fromTokens, token["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+ }
+ */
+
+ // XDC/BTC
+ fromTokens = append(fromTokens, simulation.XDCNative)
+ toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // XDC/USDT
+ fromTokens = append(fromTokens, simulation.XDCNative)
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ // ETH/XDC
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[2]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[3]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[4]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[5]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[6]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[7]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ fromTokens = append(fromTokens, tokenList[8]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ // ETH/BTC
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // XRP/BTC
+ fromTokens = append(fromTokens, tokenList[2]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // BTC/USDT
+ fromTokens = append(fromTokens, tokenList[0]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ // ETH/USDT
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ _, err = relayerRegistration.Register(simulation.RelayerCoinbaseAddr, simulation.TradeFee, fromTokens, toTokens)
+ if err != nil {
+ log.Fatal("relayerRegistration Register ", err)
+ }
+ fmt.Println("wait 2s to apply token to list XDCx")
+ time.Sleep(2 * time.Second)
+
+ // Lending apply
+ nonce = nonce + 1
+ lendingRelayerRegistration, err = XDCx.NewLendingRelayerRegistration(ownerRelayer, lendingRelayerRegistrationAddr, client)
+ if err != nil {
+ log.Fatal("NewRelayerRegistration", err)
+ }
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ lendingRelayerRegistration.TransactOpts.Value = big.NewInt(0)
+ lendingRelayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+ lendingRelayerRegistration.TransactOpts.GasLimit = uint64(10000000)
+
+ baseTokens := []common.Address{}
+ terms := []*big.Int{}
+ collaterals := []common.Address{}
+
+ // USD 1 minute for testing
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, tokenList[2]["address"].(common.Address))
+
+ // USD 1 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, tokenList[2]["address"].(common.Address))
+
+ // USD 7 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // USD 30 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 1 min
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 1 day
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 7 days
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 30 days
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 1 min
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 1 day
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 7 days
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 30 days
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ _, err = lendingRelayerRegistration.Update(simulation.RelayerCoinbaseAddr, simulation.LendingTradeFee, baseTokens, terms, collaterals)
+ if err != nil {
+ log.Fatal("lendingRelayerRegistration Update", err)
+ }
+
+ fmt.Println("wait 2s to update lending contract")
+ time.Sleep(2 * time.Second)
+}
+
+func initTRC21(auth *bind.TransactOpts, client *ethclient.Client, nonce uint64, tokenNameList []string) []map[string]interface{} {
+ tokenListResult := []map[string]interface{}{}
+ for _, tokenName := range tokenNameList {
+ auth.Nonce = big.NewInt(int64(nonce))
+ d := uint8(18)
+ depositFee := big.NewInt(0)
+ withdrawFee := big.NewInt(0)
+ tokenCap := simulation.TRC21TokenCap
+ if tokenName == "ADA" {
+ d = 0
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, simulation.BaseXDC)
+ }
+ if tokenName == "USDT" {
+ d = 6
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, big.NewInt(1000000000000))
+ withdrawFee = big.NewInt(970000)
+ }
+ if tokenName == "BTC" {
+ d = 8
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, big.NewInt(10000000000))
+ withdrawFee = big.NewInt(40000)
+ }
+ if tokenName == "ETH" {
+ withdrawFee = big.NewInt(3000000000000000)
+ }
+ tokenAddr, _, err := XDCx.DeployTRC21(auth, client, simulation.Owners, simulation.Required, tokenName, tokenName, d, tokenCap, simulation.TRC21TokenFee, depositFee, withdrawFee)
+ if err != nil {
+ log.Fatal("DeployTRC21 ", tokenName, err)
+ }
+
+ fmt.Println(tokenName+" token address", tokenAddr.Hex(), "cap", tokenCap)
+
+ tokenListResult = append(tokenListResult, map[string]interface{}{
+ "name": tokenName,
+ "address": tokenAddr,
+ "decimals": d,
+ })
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+ return tokenListResult
+}
+
+func applyIssuer(trc21Issuer *XDCx.TRC21Issuer, tokenList []map[string]interface{}, nonce uint64) {
+ for _, token := range tokenList {
+ trc21Issuer.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ trc21Issuer.TransactOpts.Value = simulation.MinTRC21Apply
+ _, err := trc21Issuer.Apply(token["address"].(common.Address))
+ if err != nil {
+ log.Fatal("trc21Issuer Apply ", token["name"].(string), err)
+ }
+ fmt.Println("applyIssuer ", token["name"].(string))
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+}
+
+func applyXDCXListing(XDCxListing *XDCx.XDCXListing, tokenList []map[string]interface{}, nonce uint64) {
+ for _, token := range tokenList {
+ XDCxListing.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ XDCxListing.TransactOpts.Value = simulation.XDCXListingFee
+ _, err := XDCxListing.Apply(token["address"].(common.Address))
+ if err != nil {
+ log.Fatal("XDCxListing Apply ", token["name"].(string), err)
+ }
+ fmt.Println("applyXDCXListing ", token["name"].(string))
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+}
+
+func airdrop(auth *bind.TransactOpts, client *ethclient.Client, tokenList []map[string]interface{}, addresses []common.Address, nonce uint64) {
+ for _, token := range tokenList {
+ for _, address := range addresses {
+ trc21Contract, _ := XDCx.NewTRC21(auth, token["address"].(common.Address), client)
+ trc21Contract.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ baseAmount := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(token["decimals"].(uint8))), nil)
+ amount := big.NewInt(0).Mul(baseAmount, big.NewInt(1000000))
+ _, err := trc21Contract.Transfer(address, amount)
+ if err == nil {
+ fmt.Printf("Transfer %v %v to %v successfully", amount.String(), token["name"].(string), address.String())
+ fmt.Println()
+ } else {
+ fmt.Printf("Transfer %v to %v failed!", token["name"].(string), address.String())
+ fmt.Println()
+ }
+ nonce = nonce + 1
+ }
+ }
+ time.Sleep(5 * time.Second)
+}
diff --git a/contracts/XDCx/simulation/fee/lending/main.go b/contracts/XDCx/simulation/fee/lending/main.go
new file mode 100644
index 0000000000..5f495f3b35
--- /dev/null
+++ b/contracts/XDCx/simulation/fee/lending/main.go
@@ -0,0 +1,52 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/simulation"
+ "math/big"
+ "os"
+ "strconv"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+)
+
+func main() {
+ client, err := ethclient.Dial(simulation.RpcEndpoint)
+ if err != nil {
+ fmt.Println(err, client)
+ }
+
+ MainKey, _ := crypto.HexToECDSA(os.Getenv("OWNER_KEY"))
+ MainAddr := crypto.PubkeyToAddress(MainKey.PublicKey)
+ coinbase := common.HexToAddress(os.Getenv("RELAYER_COINBASE"))
+ fee, _ := strconv.Atoi(os.Getenv("FEE"))
+
+ nonce, _ := client.NonceAt(context.Background(), MainAddr, nil)
+ auth := bind.NewKeyedTransactor(MainKey)
+ auth.Value = big.NewInt(0) // in wei
+ auth.GasLimit = uint64(4000000) // in units
+ auth.GasPrice = big.NewInt(250000000000000)
+
+ auth.Nonce = big.NewInt(int64(nonce))
+
+ lendContract, _ := XDCx.NewLendingRelayerRegistration(auth, common.HexToAddress("0x4d7eA2cE949216D6b120f3AA10164173615A2b6C"), client)
+
+ tx, err := lendContract.UpdateFee(coinbase, uint16(fee))
+ if err != nil {
+ fmt.Println("UpdateFee: failed!", err)
+ }
+
+ time.Sleep(5 * time.Second)
+ r, err := client.TransactionReceipt(context.Background(), tx.Hash())
+ if err != nil {
+ fmt.Println("UpdateFee: Get receipt failed", err)
+ }
+ fmt.Println("UpdateFee: Done receipt status", r.Status)
+
+}
diff --git a/contracts/XDCx/simulation/fee/trading/main.go b/contracts/XDCx/simulation/fee/trading/main.go
new file mode 100644
index 0000000000..2b562aa0eb
--- /dev/null
+++ b/contracts/XDCx/simulation/fee/trading/main.go
@@ -0,0 +1,52 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/simulation"
+ "math/big"
+ "os"
+ "strconv"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+)
+
+func main() {
+ client, err := ethclient.Dial(simulation.RpcEndpoint)
+ if err != nil {
+ fmt.Println(err, client)
+ }
+
+ MainKey, _ := crypto.HexToECDSA(os.Getenv("OWNER_KEY"))
+ MainAddr := crypto.PubkeyToAddress(MainKey.PublicKey)
+ coinbase := common.HexToAddress(os.Getenv("RELAYER_COINBASE"))
+ fee, _ := strconv.Atoi(os.Getenv("FEE"))
+
+ nonce, _ := client.NonceAt(context.Background(), MainAddr, nil)
+ auth := bind.NewKeyedTransactor(MainKey)
+ auth.Value = big.NewInt(0) // in wei
+ auth.GasLimit = uint64(4000000) // in units
+ auth.GasPrice = big.NewInt(250000000000000)
+
+ auth.Nonce = big.NewInt(int64(nonce))
+
+ registrationContract, _ := XDCx.NewRelayerRegistration(auth, common.HexToAddress("0x0342d186212b04E69eA682b3bed8e232b6b3361a"), client)
+
+ tx, err := registrationContract.UpdateFee(coinbase, uint16(fee))
+ if err != nil {
+ fmt.Println("UpdateFee: failed!", err)
+ }
+
+ time.Sleep(5 * time.Second)
+ r, err := client.TransactionReceipt(context.Background(), tx.Hash())
+ if err != nil {
+ fmt.Println("UpdateFee: Get receipt failed", err)
+ }
+ fmt.Println("UpdateFee: Done receipt status", r.Status)
+
+}
diff --git a/contracts/XDCx/simulation/price/main.go b/contracts/XDCx/simulation/price/main.go
new file mode 100644
index 0000000000..36c4bec06d
--- /dev/null
+++ b/contracts/XDCx/simulation/price/main.go
@@ -0,0 +1,67 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "math/big"
+ "os"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+)
+
+func main() {
+ client, err := ethclient.Dial("http://127.0.0.1:8501/")
+ if err != nil {
+ fmt.Println(err, client)
+ }
+ MainKey, _ := crypto.HexToECDSA(os.Getenv("OWNER_KEY"))
+ MainAddr := crypto.PubkeyToAddress(MainKey.PublicKey)
+
+ nonce, _ := client.NonceAt(context.Background(), MainAddr, nil)
+ auth := bind.NewKeyedTransactor(MainKey)
+ auth.Value = big.NewInt(0) // in wei
+ auth.GasLimit = uint64(4000000) // in units
+ auth.GasPrice = big.NewInt(250000000000000)
+
+ // init trc21 issuer
+ auth.Nonce = big.NewInt(int64(nonce))
+
+ price := new(big.Int)
+ price.SetString(os.Getenv("PRICE"), 10)
+
+ lendContract, _ := XDCx.NewLendingRelayerRegistration(auth, common.HexToAddress(os.Getenv("LENDING_ADDRESS")), client)
+
+ token := common.HexToAddress(os.Getenv("TOKEN_ADDRESS"))
+ lendingToken := common.HexToAddress(os.Getenv("LENDING_TOKEN_ADDRESS"))
+
+ tx, err := lendContract.SetCollateralPrice(token, lendingToken, price)
+ if err != nil {
+ fmt.Println("Set price failed!", err)
+ }
+
+ time.Sleep(5 * time.Second)
+ r, err := client.TransactionReceipt(context.Background(), tx.Hash())
+ if err != nil {
+ fmt.Println("Get receipt failed", err)
+ }
+ fmt.Println("Done receipt status", r.Status)
+
+ collateralState := state.GetLocMappingAtKey(token.Hash(), lendingstate.CollateralMapSlot)
+ locMapPrices := collateralState.Add(collateralState, lendingstate.CollateralStructSlots["price"])
+ locLendingTokenPriceByte := crypto.Keccak256(lendingToken.Hash().Bytes(), common.BigToHash(locMapPrices).Bytes())
+
+ locCollateralPrice := common.BigToHash(new(big.Int).Add(new(big.Int).SetBytes(locLendingTokenPriceByte), lendingstate.PriceStructSlots["price"]))
+ locBlockNumber := common.BigToHash(new(big.Int).Add(new(big.Int).SetBytes(locLendingTokenPriceByte), lendingstate.PriceStructSlots["blockNumber"]))
+
+ priceByte, err := client.StorageAt(context.Background(), common.HexToAddress(os.Getenv("LENDING_ADDRESS")), locCollateralPrice, nil)
+ fmt.Println(new(big.Int).SetBytes(priceByte), err)
+ blockNumberByte, err := client.StorageAt(context.Background(), common.HexToAddress(os.Getenv("LENDING_ADDRESS")), locBlockNumber, nil)
+ fmt.Println(new(big.Int).SetBytes(blockNumberByte), err)
+}
diff --git a/contracts/XDCx/testnet/constants.go b/contracts/XDCx/testnet/constants.go
new file mode 100644
index 0000000000..de4d44d44d
--- /dev/null
+++ b/contracts/XDCx/testnet/constants.go
@@ -0,0 +1,68 @@
+package testnet
+
+import (
+ "math/big"
+ "os"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+)
+
+var (
+ BaseXDC = big.NewInt(0).Mul(big.NewInt(10), big.NewInt(100000000000000000)) // 1 XDC
+ RpcEndpoint = "http://127.0.0.1:8545/"
+ MainKey, _ = crypto.HexToECDSA(os.Getenv("MAIN_ADDRESS_KEY"))
+ MainAddr = crypto.PubkeyToAddress(MainKey.PublicKey) //0x17F2beD710ba50Ed27aEa52fc4bD7Bda5ED4a037
+
+ // TRC21 Token
+ MinTRC21Apply = big.NewInt(0).Mul(big.NewInt(10), BaseXDC) // 10 XDC
+ TRC21TokenCap = big.NewInt(0).Mul(big.NewInt(1000000000000), BaseXDC)
+ TRC21TokenFee = big.NewInt(0)
+ XDCXListingFee = big.NewInt(0).Mul(big.NewInt(1000), BaseXDC) // 1000 XDC
+
+ // XDCX
+ MaxRelayers = big.NewInt(200)
+ MaxTokenList = big.NewInt(200)
+ MinDeposit = big.NewInt(0).Mul(big.NewInt(25000), BaseXDC) // 25000 XDC
+ CollateralDepositRate = big.NewInt(150)
+ CollateralLiquidationRate = big.NewInt(110)
+ CollateralRecallRate = big.NewInt(200)
+ TradeFee = uint16(10) // trade fee decimals 10^4
+ LendingTradeFee = uint16(100) // lending trade fee decimals 10^4
+ // 1m , 1d,7d,30d
+ Terms = []*big.Int{big.NewInt(60), big.NewInt(86400), big.NewInt(7 * 86400), big.NewInt(30 * 86400)}
+ RelayerCoinbaseKey, _ = crypto.HexToECDSA(os.Getenv("RELAYER_COINBASE_KEY")) //
+ RelayerCoinbaseAddr = crypto.PubkeyToAddress(RelayerCoinbaseKey.PublicKey) // 0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
+
+ OwnerRelayerKey, _ = crypto.HexToECDSA(os.Getenv("RELAYER_OWNER_KEY"))
+ OwnerRelayerAddr = crypto.PubkeyToAddress(OwnerRelayerKey.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
+
+ XDCNative = common.HexToAddress("0x0000000000000000000000000000000000000001")
+
+ TokenNameList = []string{"BTC", "ETH", "XRP", "LTC", "BNB", "ADA", "ETC", "BCH", "EOS", "USDT"}
+ TeamAddresses = []common.Address{
+ common.HexToAddress("0xE3584D2D430eF34FF9fEeCBEBE6E0f6980082F05"), // Test1
+ common.HexToAddress("0x16a73f3a64eca79e117258e66dfd7071cc8312a9"), // BTCXDC
+ common.HexToAddress("0xac177441ac2237b2f79ecff1b8f6bca39e27ef9f"), // ETHXDC
+ common.HexToAddress("0x4215250e55984c75bbce8ae639b86a6cad8ec126"), // XRPXDC
+ common.HexToAddress("0x6b70ca959814866dd5c426d63d47dde9cc6c32d2"), // LTCXDC
+ common.HexToAddress("0x33df079fe9b9cd7fb23a1085e4eaaa8eb6952cb3"), // BNBXDC
+ common.HexToAddress("0x3cab8292137804688714670640d19f9d7a60c472"), // ADAXDC
+ common.HexToAddress("0x9415d953d47c5f155cac9de7b24a756f352eafbf"), // ETCXDC
+ common.HexToAddress("0xe32d2e7c8e8809e45c8e2332830b48d9e231e3f2"), // BCHXDC
+ common.HexToAddress("0xf76ddbda664ea47088937e1cf9ff15036714dee3"), // EOSXDC
+ common.HexToAddress("0xc465ee82440dada9509feb235c7cd7d896acf13c"), // ETHBTC
+ common.HexToAddress("0xb95bdc136c579dc3fd2b2424a8e925a90228d2c2"), // XRPBTC
+ common.HexToAddress("0xe36c1842365595D44854eEcd64B11c8115E133EF"), // XDCUSDT
+ common.HexToAddress("0xaaC1959F6F0fb539F653409079Ec4146267B7555"), // BTCUSDT
+ common.HexToAddress("0x726DA688e2e09f01A2e1aB4c10F25B7CEdD4a0f3"), // ETHUSDT
+
+ }
+
+ Required = big.NewInt(2)
+ Owners = []common.Address{
+ common.HexToAddress("0x244e17B2141288a6F00E79E8feC2341f827d156f"),
+ common.HexToAddress("0xd106159eC58BD2EAf5B62eF4e9cDb286170B0Bb9"),
+ common.HexToAddress("0x0197BE034Bf0Bd2b3adDC84366a5681Bb7545888"),
+ }
+)
diff --git a/contracts/XDCx/testnet/deploy/main.go b/contracts/XDCx/testnet/deploy/main.go
new file mode 100644
index 0000000000..33d4195f61
--- /dev/null
+++ b/contracts/XDCx/testnet/deploy/main.go
@@ -0,0 +1,423 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "math/big"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx"
+ simulation "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/testnet"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+)
+
+func main() {
+ fmt.Println("========================")
+ fmt.Println("mainAddr", simulation.MainAddr.Hex())
+ fmt.Println("relayerAddr", simulation.RelayerCoinbaseAddr.Hex())
+ fmt.Println("ownerRelayerAddr", simulation.OwnerRelayerAddr.Hex())
+ fmt.Println("========================")
+ client, err := ethclient.Dial(simulation.RpcEndpoint)
+ if err != nil {
+ fmt.Println(err, client)
+ }
+ nonce, _ := client.NonceAt(context.Background(), simulation.MainAddr, nil)
+ auth := bind.NewKeyedTransactor(simulation.MainKey)
+ auth.Value = big.NewInt(0) // in wei
+ auth.GasLimit = uint64(10000000) // in units
+ auth.GasPrice = big.NewInt(250000000000000)
+
+ // init trc21 issuer
+ auth.Nonce = big.NewInt(int64(nonce))
+ trc21IssuerAddr, trc21Issuer, err := XDCx.DeployTRC21Issuer(auth, client, simulation.MinTRC21Apply)
+ if err != nil {
+ log.Fatal("DeployTRC21Issuer", err)
+ }
+ trc21Issuer.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> trc21 issuer address", trc21IssuerAddr.Hex())
+ fmt.Println("wait 10s to execute init smart contract : TRC Issuer")
+ time.Sleep(2 * time.Second)
+
+ //init XDCX Listing in
+ auth.Nonce = big.NewInt(int64(nonce + 1))
+ XDCxListtingAddr, XDCxListing, err := XDCx.DeployXDCXListing(auth, client)
+ if err != nil {
+ log.Fatal("DeployXDCXListing", err)
+ }
+ XDCxListing.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> XDCx listing address", XDCxListtingAddr.Hex())
+ fmt.Println("wait 10s to execute init smart contract : XDCx listing ")
+ time.Sleep(2 * time.Second)
+
+ // init Relayer Registration
+ auth.Nonce = big.NewInt(int64(nonce + 2))
+ relayerRegistrationAddr, relayerRegistration, err := XDCx.DeployRelayerRegistration(auth, client, XDCxListtingAddr, simulation.MaxRelayers, simulation.MaxTokenList, simulation.MinDeposit)
+ if err != nil {
+ log.Fatal("DeployRelayerRegistration", err)
+ }
+ relayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> relayer registration address", relayerRegistrationAddr.Hex())
+ fmt.Println("wait 2s to execute init smart contract : relayer registration ")
+ time.Sleep(2 * time.Second)
+
+ auth.Nonce = big.NewInt(int64(nonce + 3))
+ lendingRelayerRegistrationAddr, lendingRelayerRegistration, err := XDCx.DeployLendingRelayerRegistration(auth, client, relayerRegistrationAddr, XDCxListtingAddr)
+ if err != nil {
+ log.Fatal("DeployLendingRelayerRegistration", err)
+ }
+ lendingRelayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fmt.Println("===> lending relayer registration address", lendingRelayerRegistrationAddr.Hex())
+ fmt.Println("wait 2s to execute init smart contract : lending relayer registration ")
+ time.Sleep(2 * time.Second)
+
+ currentNonce := nonce + 4
+ tokenList := initTRC21(auth, client, currentNonce, simulation.TokenNameList)
+
+ currentNonce = currentNonce + uint64(len(simulation.TokenNameList)) // init smartcontract
+
+ applyIssuer(trc21Issuer, tokenList, currentNonce)
+
+ currentNonce = currentNonce + uint64(len(simulation.TokenNameList))
+ applyXDCXListing(XDCxListing, tokenList, currentNonce)
+
+ // BTC Collateral
+ nonce = currentNonce + uint64(len(simulation.TokenNameList))
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(tokenList[0]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // ETH Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(tokenList[1]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // XDC Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddCollateral(simulation.XDCNative, simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+
+ if err != nil {
+ log.Fatal("Lending add collateral", err)
+ }
+
+ // XRP ILO Collateral
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddILOCollateral(tokenList[2]["address"].(common.Address), simulation.CollateralDepositRate, simulation.CollateralLiquidationRate, simulation.CollateralRecallRate)
+ if err != nil {
+ log.Fatal("Lending add ILO collateral", err)
+ }
+
+ // USD lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(tokenList[9]["address"].(common.Address))
+ if err != nil {
+ log.Fatal("Lending add base token USD", err)
+ }
+
+ // XDC lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(simulation.XDCNative)
+ if err != nil {
+ log.Fatal("Lending add base token XDC", err)
+ }
+
+ // BTC lending base
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddBaseToken(tokenList[0]["address"].(common.Address))
+ if err != nil {
+ log.Fatal("Lending add base token BTC", err)
+ }
+
+ // add term 1 minute for testing
+ for i := 0; i < len(simulation.Terms); i++ {
+ nonce = nonce + 1
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ _, err = lendingRelayerRegistration.AddTerm(simulation.Terms[i])
+ if err != nil {
+ log.Fatal("Lending add terms", err)
+ }
+ fmt.Println("wait 2s to add term lending lending contract", simulation.Terms[i])
+ time.Sleep(2 * time.Second)
+ }
+ fmt.Println("wait 2s to setup lending contract")
+ time.Sleep(2 * time.Second)
+
+ currentNonce = nonce + 1
+ airdrop(auth, client, tokenList, simulation.TeamAddresses, currentNonce)
+
+ // relayer registration
+ ownerRelayer := bind.NewKeyedTransactor(simulation.OwnerRelayerKey)
+ nonce, _ = client.NonceAt(context.Background(), simulation.OwnerRelayerAddr, nil)
+ relayerRegistration, err = XDCx.NewRelayerRegistration(ownerRelayer, relayerRegistrationAddr, client)
+ if err != nil {
+ log.Fatal("NewRelayerRegistration", err)
+ }
+ relayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ relayerRegistration.TransactOpts.Value = simulation.MinDeposit
+ relayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+
+ fromTokens := []common.Address{}
+ toTokens := []common.Address{}
+
+ /*
+ for _, token := range tokenList {
+ fromTokens = append(fromTokens, token["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+ }
+ */
+
+ // XDC/BTC
+ fromTokens = append(fromTokens, simulation.XDCNative)
+ toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // XDC/USDT
+ fromTokens = append(fromTokens, simulation.XDCNative)
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ // ETH/XDC
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[2]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[3]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[4]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[5]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[6]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[7]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ //fromTokens = append(fromTokens, tokenList[8]["address"].(common.Address))
+ //toTokens = append(toTokens, simulation.XDCNative)
+
+ // ETH/BTC
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // XRP/BTC
+ //fromTokens = append(fromTokens, tokenList[2]["address"].(common.Address))
+ //toTokens = append(toTokens, tokenList[0]["address"].(common.Address))
+
+ // BTC/USDT
+ fromTokens = append(fromTokens, tokenList[0]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ // ETH/USDT
+ fromTokens = append(fromTokens, tokenList[1]["address"].(common.Address))
+ toTokens = append(toTokens, tokenList[9]["address"].(common.Address))
+
+ _, err = relayerRegistration.Register(simulation.RelayerCoinbaseAddr, simulation.TradeFee, fromTokens, toTokens)
+ if err != nil {
+ log.Fatal("relayerRegistration Register ", err)
+ }
+ fmt.Println("wait 2s to apply token to list XDCx")
+ time.Sleep(2 * time.Second)
+
+ // Lending apply
+ nonce = nonce + 1
+ lendingRelayerRegistration, err = XDCx.NewLendingRelayerRegistration(ownerRelayer, lendingRelayerRegistrationAddr, client)
+ if err != nil {
+ log.Fatal("NewRelayerRegistration", err)
+ }
+ lendingRelayerRegistration.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ lendingRelayerRegistration.TransactOpts.Value = big.NewInt(0)
+ lendingRelayerRegistration.TransactOpts.GasPrice = big.NewInt(250000000000000)
+ lendingRelayerRegistration.TransactOpts.GasLimit = uint64(10000000)
+
+ baseTokens := []common.Address{}
+ terms := []*big.Int{}
+ collaterals := []common.Address{}
+
+ // USD 1 minute for testing
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, tokenList[2]["address"].(common.Address))
+
+ // USD 1 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, tokenList[2]["address"].(common.Address))
+
+ // USD 7 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // USD 30 days
+ baseTokens = append(baseTokens, tokenList[9]["address"].(common.Address))
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 1 min
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 1 day
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 7 days
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // XDC 30 days
+ baseTokens = append(baseTokens, simulation.XDCNative)
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 1 min
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(60))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 1 day
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 7 days
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(7*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ // BTC 30 days
+ baseTokens = append(baseTokens, tokenList[0]["address"].(common.Address))
+ terms = append(terms, big.NewInt(30*86400))
+ collaterals = append(collaterals, common.HexToAddress("0x0"))
+
+ _, err = lendingRelayerRegistration.Update(simulation.RelayerCoinbaseAddr, simulation.LendingTradeFee, baseTokens, terms, collaterals)
+ if err != nil {
+ log.Fatal("lendingRelayerRegistration Update", err)
+ }
+
+ fmt.Println("wait 2s to update lending contract")
+ time.Sleep(2 * time.Second)
+}
+
+func initTRC21(auth *bind.TransactOpts, client *ethclient.Client, nonce uint64, tokenNameList []string) []map[string]interface{} {
+ tokenListResult := []map[string]interface{}{}
+ for _, tokenName := range tokenNameList {
+ auth.Nonce = big.NewInt(int64(nonce))
+ d := uint8(18)
+ depositFee := big.NewInt(0)
+ withdrawFee := big.NewInt(0)
+ tokenCap := simulation.TRC21TokenCap
+ if tokenName == "ADA" {
+ d = 0
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, simulation.BaseXDC)
+ }
+ if tokenName == "USDT" {
+ d = 6
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, big.NewInt(1000000000000))
+ withdrawFee = big.NewInt(970000)
+ }
+ if tokenName == "BTC" {
+ d = 8
+ tokenCap = new(big.Int).Div(simulation.TRC21TokenCap, big.NewInt(10000000000))
+ withdrawFee = big.NewInt(40000)
+ }
+ if tokenName == "ETH" {
+ withdrawFee = big.NewInt(3000000000000000)
+ }
+ tokenAddr, _, err := XDCx.DeployTRC21(auth, client, simulation.Owners, simulation.Required, tokenName, tokenName, d, tokenCap, simulation.TRC21TokenFee, depositFee, withdrawFee)
+ if err != nil {
+ log.Fatal("DeployTRC21 ", tokenName, err)
+ }
+
+ fmt.Println(tokenName+" token address", tokenAddr.Hex(), "cap", tokenCap)
+
+ tokenListResult = append(tokenListResult, map[string]interface{}{
+ "name": tokenName,
+ "address": tokenAddr,
+ "decimals": d,
+ })
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+ return tokenListResult
+}
+
+func applyIssuer(trc21Issuer *XDCx.TRC21Issuer, tokenList []map[string]interface{}, nonce uint64) {
+ for _, token := range tokenList {
+ trc21Issuer.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ trc21Issuer.TransactOpts.Value = simulation.MinTRC21Apply
+ _, err := trc21Issuer.Apply(token["address"].(common.Address))
+ if err != nil {
+ log.Fatal("trc21Issuer Apply ", token["name"].(string), err)
+ }
+ fmt.Println("applyIssuer ", token["name"].(string))
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+}
+
+func applyXDCXListing(XDCxListing *XDCx.XDCXListing, tokenList []map[string]interface{}, nonce uint64) {
+ for _, token := range tokenList {
+ XDCxListing.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ XDCxListing.TransactOpts.Value = simulation.XDCXListingFee
+ _, err := XDCxListing.Apply(token["address"].(common.Address))
+ if err != nil {
+ log.Fatal("XDCxListing Apply ", token["name"].(string), err)
+ }
+ fmt.Println("applyXDCXListing ", token["name"].(string))
+ nonce = nonce + 1
+ }
+ time.Sleep(5 * time.Second)
+}
+
+func airdrop(auth *bind.TransactOpts, client *ethclient.Client, tokenList []map[string]interface{}, addresses []common.Address, nonce uint64) {
+ for _, token := range tokenList {
+ for _, address := range addresses {
+ trc21Contract, _ := XDCx.NewTRC21(auth, token["address"].(common.Address), client)
+ trc21Contract.TransactOpts.Nonce = big.NewInt(int64(nonce))
+ baseAmount := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(token["decimals"].(uint8))), nil)
+ amount := big.NewInt(0).Mul(baseAmount, big.NewInt(1000000))
+ _, err := trc21Contract.Transfer(address, amount)
+ if err == nil {
+ fmt.Printf("Transfer %v %v to %v successfully", amount.String(), token["name"].(string), address.String())
+ fmt.Println()
+ } else {
+ fmt.Printf("Transfer %v to %v failed!", token["name"].(string), address.String())
+ fmt.Println()
+ }
+ nonce = nonce + 1
+ }
+ }
+ time.Sleep(5 * time.Second)
+}
diff --git a/contracts/XDCx/trc21.go b/contracts/XDCx/trc21.go
new file mode 100644
index 0000000000..dc3539b5ea
--- /dev/null
+++ b/contracts/XDCx/trc21.go
@@ -0,0 +1,41 @@
+package XDCx
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+ "math/big"
+)
+
+type MyTRC21 struct {
+ *contract.MyTRC21Session
+ contractBackend bind.ContractBackend
+}
+
+func NewTRC21(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*MyTRC21, error) {
+ smartContract, err := contract.NewMyTRC21(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &MyTRC21{
+ &contract.MyTRC21Session{
+ Contract: smartContract,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployTRC21(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, owners []common.Address, required *big.Int, name string, symbol string, decimals uint8, cap, fee, depositFee, withdrawFee *big.Int) (common.Address, *MyTRC21, error) {
+ contractAddr, _, _, err := contract.DeployMyTRC21(transactOpts, contractBackend, owners, required, name, symbol, decimals, cap, fee, depositFee, withdrawFee)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ smartContract, err := NewTRC21(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, smartContract, nil
+}
diff --git a/contracts/XDCx/trc21Issuer.go b/contracts/XDCx/trc21Issuer.go
new file mode 100644
index 0000000000..d28182d1cc
--- /dev/null
+++ b/contracts/XDCx/trc21Issuer.go
@@ -0,0 +1,41 @@
+package XDCx
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+ "math/big"
+)
+
+type TRC21Issuer struct {
+ *contract.TRC21IssuerSession
+ contractBackend bind.ContractBackend
+}
+
+func NewTRC21Issuer(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*TRC21Issuer, error) {
+ contractObject, err := contract.NewTRC21Issuer(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &TRC21Issuer{
+ &contract.TRC21IssuerSession{
+ Contract: contractObject,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployTRC21Issuer(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, minApply *big.Int) (common.Address, *TRC21Issuer, error) {
+ contractAddr, _, _, err := contract.DeployTRC21Issuer(transactOpts, contractBackend, minApply)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ contractObject, err := NewTRC21Issuer(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, contractObject, nil
+}
diff --git a/contracts/blocksigner/blocksigner.go b/contracts/blocksigner/blocksigner.go
index 724dddbf90..f3bd3273cc 100644
--- a/contracts/blocksigner/blocksigner.go
+++ b/contracts/blocksigner/blocksigner.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -16,11 +16,10 @@
package blocksigner
import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/contract"
"math/big"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
)
type BlockSigner struct {
diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go
index 5a83bf7194..0a649ea2f6 100644
--- a/contracts/blocksigner/blocksigner_test.go
+++ b/contracts/blocksigner/blocksigner_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -21,13 +21,12 @@ import (
"testing"
"time"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
"math/rand"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
)
var (
diff --git a/contracts/blocksigner/contract/blocksigner.go b/contracts/blocksigner/contract/blocksigner.go
index 385c1f525c..4a5b8d15d6 100644
--- a/contracts/blocksigner/contract/blocksigner.go
+++ b/contracts/blocksigner/contract/blocksigner.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// BlockSignerABI is the input ABI used to generate the binding from.
diff --git a/contracts/chequebook/api.go b/contracts/chequebook/api.go
index b2b2365f31..1503caa699 100644
--- a/contracts/chequebook/api.go
+++ b/contracts/chequebook/api.go
@@ -20,7 +20,7 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
const Version = "1.0"
diff --git a/contracts/chequebook/cheque.go b/contracts/chequebook/cheque.go
index 92bd896e0a..f956c3f2b1 100644
--- a/contracts/chequebook/cheque.go
+++ b/contracts/chequebook/cheque.go
@@ -36,14 +36,14 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/services/swap/swap"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/contracts/chequebook/contract"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/swarm/services/swap/swap"
)
// TODO(zelig): watch peer solvency and notify of bouncing cheques
diff --git a/contracts/chequebook/cheque_test.go b/contracts/chequebook/cheque_test.go
index 6b6b28e657..dbf28f69e1 100644
--- a/contracts/chequebook/cheque_test.go
+++ b/contracts/chequebook/cheque_test.go
@@ -24,12 +24,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/chequebook/contract"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/contracts/chequebook/contract/chequebook.go b/contracts/chequebook/contract/chequebook.go
index e275ac9b8d..cee0c2f3da 100644
--- a/contracts/chequebook/contract/chequebook.go
+++ b/contracts/chequebook/contract/chequebook.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// ChequebookABI is the input ABI used to generate the binding from.
diff --git a/contracts/chequebook/gencode.go b/contracts/chequebook/gencode.go
index 45f6d68f3e..2f58e8a05d 100644
--- a/contracts/chequebook/gencode.go
+++ b/contracts/chequebook/gencode.go
@@ -25,11 +25,11 @@ import (
"io/ioutil"
"math/big"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/contracts/chequebook/contract"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/contracts/ens/contract/ens.go b/contracts/ens/contract/ens.go
index cbf6cb05b3..68418c45a1 100644
--- a/contracts/ens/contract/ens.go
+++ b/contracts/ens/contract/ens.go
@@ -6,12 +6,12 @@ package contract
import (
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// ENSABI is the input ABI used to generate the binding from.
diff --git a/contracts/ens/contract/fifsregistrar.go b/contracts/ens/contract/fifsregistrar.go
index a08380adfc..ad431b467e 100644
--- a/contracts/ens/contract/fifsregistrar.go
+++ b/contracts/ens/contract/fifsregistrar.go
@@ -6,10 +6,10 @@ package contract
import (
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// FIFSRegistrarABI is the input ABI used to generate the binding from.
diff --git a/contracts/ens/contract/publicresolver.go b/contracts/ens/contract/publicresolver.go
index c567d5884a..a7ac9ab0ef 100644
--- a/contracts/ens/contract/publicresolver.go
+++ b/contracts/ens/contract/publicresolver.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// PublicResolverABI is the input ABI used to generate the binding from.
diff --git a/contracts/ens/ens.go b/contracts/ens/ens.go
index 06045a5cd8..d12efa690c 100644
--- a/contracts/ens/ens.go
+++ b/contracts/ens/ens.go
@@ -23,11 +23,11 @@ package ens
import (
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/ens/contract"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/ens/contract"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/contracts/ens/ens_test.go b/contracts/ens/ens_test.go
index 0016f47dbf..6b6facbccc 100644
--- a/contracts/ens/ens_test.go
+++ b/contracts/ens/ens_test.go
@@ -20,11 +20,11 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/contracts/ens/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/contracts/ens/contract"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/contracts/multisigwallet/contract/multisigwallet.go b/contracts/multisigwallet/contract/multisigwallet.go
index 8cd1109197..f73bc09424 100644
--- a/contracts/multisigwallet/contract/multisigwallet.go
+++ b/contracts/multisigwallet/contract/multisigwallet.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// MultiSigWalletABI is the input ABI used to generate the binding from.
diff --git a/contracts/multisigwallet/multisigwallet.go b/contracts/multisigwallet/multisigwallet.go
index fd42811192..943fa80a43 100644
--- a/contracts/multisigwallet/multisigwallet.go
+++ b/contracts/multisigwallet/multisigwallet.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -16,11 +16,10 @@
package multisigwallet
import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/multisigwallet/contract"
"math/big"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/multisigwallet/contract"
)
type MultiSigWallet struct {
diff --git a/contracts/randomize/contract/randomize.go b/contracts/randomize/contract/randomize.go
index 9234556f10..92c3f71c35 100644
--- a/contracts/randomize/contract/randomize.go
+++ b/contracts/randomize/contract/randomize.go
@@ -6,10 +6,10 @@ package contract
import (
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// SafeMathABI is the input ABI used to generate the binding from.
diff --git a/contracts/randomize/randomize.go b/contracts/randomize/randomize.go
index 8a5fd0999e..b0bbd90016 100644
--- a/contracts/randomize/randomize.go
+++ b/contracts/randomize/randomize.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -16,9 +16,9 @@
package randomize
import (
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/randomize/contract"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/randomize/contract"
)
type Randomize struct {
diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go
index 4f44047a18..063b2832b6 100644
--- a/contracts/randomize/randomize_test.go
+++ b/contracts/randomize/randomize_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -21,13 +21,13 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/contracts/solidity_0.6/README.md b/contracts/solidity_0.6/README.md
new file mode 100644
index 0000000000..be315a3f1a
--- /dev/null
+++ b/contracts/solidity_0.6/README.md
@@ -0,0 +1,185 @@
+# What’s new in Solidity 0.6 ?
+
+[Solidity 0.6](https://solidity.readthedocs.io/en/v0.6.2/060-breaking-changes.html) was recently released, bringing a few syntactical changes and non-backward compatible changes.
+
+Let's take a look at some of the major changes:
+
+- Function Overriding
+- Abstract Contracts
+- Try / Catch
+- Receive Ether / Fallback Function split
+- Array Resizing
+- State variable shadowing
+
+### Function Overriding
+In previous Solidity versions, there was no explicit way to know which functions an inheriting contract should override. Solidity 0.6 brings with it an improvement that makes it clear which functions an inheriting contract can override.
+
+An inheriting contract can override its base contract function behavior only if they are marked as virtual. The overriding function must then use the override keyword in the function header as shown below.
+
+```
+pragma solidity ^0.6.0;
+contract Base1
+{
+ function foo() virtual public {}
+}
+contract Base2
+{
+ function foo() virtual public {}
+}
+contract Inherited is Base1, Base2
+{
+ // Derives from multiple bases defining foo(), so we must explicitly
+ // override it
+ function foo() public override(Base1, Base2) {}
+}
+```
+
+With this improvement no more checking OpenZeppelin docs as to which functions can be overridden as the Solidity compiler itself can let you know when an inheriting contract overrides a no `virtual` function.
+
+### Abstract Contracts
+A new keyword abstract was introduced in Solidity 0.6. It is used to mark contracts that do not implement all its functions.
+
+Contracts are to be marked as abstractwhen at least one of their functions is not implemented. Functions without implementation outside an interface have to be marked virtual. Contracts can also be marked as abstract even though all functions are implemented.
+
+```
+pragma solidity ^0.6.0;
+abstract contract Feline {
+ function utterance() public virtual returns (bytes32);
+}
+contract Cat is Feline {
+ function utterance() public override returns (bytes32) {
+ return "miaow";
+ }
+}
+
+```
+
+### Try / Catch
+Solidity 0.6 introduces a try/catch statement for handling failed contract call errors. It allows you to react to failed external calls.
+
+A failure in an external contract call can be caught using a try/catch statement, as follows:
+
+```pragma solidity ^0.6.0;
+interface DataFeed {
+ function getData(address token) external returns (uint value);
+}
+contract FeedConsumer {
+ DataFeed feed;
+ uint errorCount;
+ function rate(address token) public returns (uint value, bool success) {
+ // Permanently disable the mechanism if there are
+ // more than 10 errors.
+ require(errorCount < 10);
+ try feed.getData(token) returns (uint v) {
+ return (v, true);
+ } catch Error(string memory /*reason*/) {
+ // This is executed in case
+ // revert was called inside getData
+ // and a reason string was provided.
+ errorCount++;
+ return (0, false);
+ } catch (bytes memory /*lowLevelData*/) {
+ // This is executed in case revert() was used
+ // or there was a failing assertion, division
+ // by zero, etc. inside getData.
+ errorCount++;
+ return (0, false);
+ }
+ }
+}
+```
+
+Solidity supports different kinds of catch blocks depending on the type of error. If the error was caused by `revert("reasonString") or require(false, "reasonString")` (or an internal error that causes such an exception), then the catch clause of the type `catch Error(string memory reason)` will be executed.
+
+### Receive Ether / Fallback Function Split
+#### Receive Ether
+To enable a contract to receive Ether, it must implement `the receive()` function. A contract can have at most one receive function, declared using `receive() external payable { ... }` (without the `function` keyword) as shown in the example below:
+
+```
+pragma solidity ^0.6.0;
+// This contract keeps all Ether sent to it with no way
+// to get it back.
+contract Sink {
+ event Received(address, uint);
+ receive() external payable {
+ emit Received(msg.sender, msg.value);
+ }
+}
+```
+
+#### Fallback Function
+A contract can have at most one fallback function, declared using `fallback () external [payable]` (without the `function` keyword). This function cannot have arguments, cannot return anything and must have external visibility. It is executed on a call to the contract if none of the other functions match the given function signature, or if no data was supplied at all and there is no [receive Ether function](https://solidity.readthedocs.io/en/v0.6.2/contracts.html#receive-ether-function). The fallback function always receives data, but in order to also receive Ether it must be marked payable.
+
+```
+pragma solidity >0.6.1 <0.7.0;
+contract Test {
+ // This function is called for all messages sent to
+ // this contract (there is no other function).
+ // Sending Ether to this contract will cause an exception,
+ // because the fallback function does not have the `payable`
+ // modifier.
+ fallback() external { x = 1; }
+ uint x;
+}
+contract TestPayable {
+ // This function is called for all messages sent to
+ // this contract, except plain Ether transfers
+ // (there is no other function except the receive function).
+ // Any call with non-empty calldata to this contract will execute
+ // the fallback function (even if Ether is sent along with the call).
+ fallback() external payable { x = 1; y = msg.value; }
+// This function is called for plain Ether transfers, i.e.
+ // for every call with empty calldata.
+ receive() external payable { x = 2; y = msg.value; }
+ uint x;
+ uint y;
+}
+```
+
+### Array Resizing
+Access to length of arrays is now always read-only, even for storage arrays. It is no longer possible to resize storage arrays assigning a new value to their length. Use push(), push(value) or pop() instead, or assign a full array,
+
+- Change `uint length = array.push(value)` to `array.push(value);`. The new length can be accessed via `array.length`.
+
+- Change `array.length++` to `array.push()` to increase, and use `pop()` to decrease the length of a storage array.
+
+```
+pragma solidity ^0.6.0;
+contract Test {
+ string[] public names_A_to_F;
+ function test() public {
+ // invalid syntax
+ uint length = names_A_to_F.push("Alice"); // invalid
+ names_A_to_F.length++; // invalid as length is now read only
+ // correct syntax
+ names_A_to_F.push(); // increase array length
+ names_A_to_F.push("Alice"); // add item to array
+ names_A_to_F.pop(); // reduce array length by removing item
+ uint length = names_A_to_F.length; // access array length
+ }
+}
+
+
+```
+
+### State variable shadowing is now disallowed
+State variable shadowing is considered as an error. A derived contract can only declare a state variable x, if there is no visible state variable with the same name in any of its bases.
+
+An example is shown below:
+
+```
+pragma solidity ^0.6.0;
+contract Test {
+ address x;
+}
+contract TestOverride is Test {
+// This declaration would throw an error because its shadowing a
+// state variable already in its base inherited contract Test
+ address x;
+}
+
+
+```
+This is an explicit requirement that furthers helps improve reading and understanding a Solidity codebase.
+
+Source: [Coinmonks blog](https://medium.com/coinmonks/whats-new-in-solidity-0-6-56fa76198ec7)
diff --git a/contracts/solidity_0.6/abstract.sol b/contracts/solidity_0.6/abstract.sol
new file mode 100644
index 0000000000..4811ee270c
--- /dev/null
+++ b/contracts/solidity_0.6/abstract.sol
@@ -0,0 +1,9 @@
+pragma solidity ^0.6.0;
+abstract contract Feline {
+ function utterance() public virtual returns (bytes32);
+}
+contract Cat is Feline {
+ function utterance() public override returns (bytes32) {
+ return "miaow";
+ }
+}
diff --git a/contracts/solidity_0.6/array_resizing.sol b/contracts/solidity_0.6/array_resizing.sol
new file mode 100644
index 0000000000..a44eeff811
--- /dev/null
+++ b/contracts/solidity_0.6/array_resizing.sol
@@ -0,0 +1,15 @@
+pragma solidity ^0.6.0;
+contract Test {
+ string[] public names_A_to_F;
+ function test() public {
+ // invalid syntax
+ uint length = names_A_to_F.push("Alice"); // invalid
+ names_A_to_F.length++; // invalid as length is now read only
+ // correct syntax
+ names_A_to_F.push(); // increase array length
+ names_A_to_F.push("Alice"); // add item to array
+ names_A_to_F.pop(); // reduce array length by removing item
+ uint length = names_A_to_F.length; // access array length
+ }
+}
+
diff --git a/contracts/solidity_0.6/fallback.sol b/contracts/solidity_0.6/fallback.sol
new file mode 100644
index 0000000000..e693f6cc3e
--- /dev/null
+++ b/contracts/solidity_0.6/fallback.sol
@@ -0,0 +1,23 @@
+pragma solidity >0.6.1 <0.7.0;
+contract Test {
+ // This function is called for all messages sent to
+ // this contract (there is no other function).
+ // Sending Ether to this contract will cause an exception,
+ // because the fallback function does not have the `payable`
+ // modifier.
+ fallback() external { x = 1; }
+ uint x;
+}
+contract TestPayable {
+ // This function is called for all messages sent to
+ // this contract, except plain Ether transfers
+ // (there is no other function except the receive function).
+ // Any call with non-empty calldata to this contract will execute
+ // the fallback function (even if Ether is sent along with the call).
+ fallback() external payable { x = 1; y = msg.value; }
+// This function is called for plain Ether transfers, i.e.
+ // for every call with empty calldata.
+ receive() external payable { x = 2; y = msg.value; }
+ uint x;
+ uint y;
+}
diff --git a/contracts/solidity_0.6/overriding.sol b/contracts/solidity_0.6/overriding.sol
new file mode 100644
index 0000000000..899c093c2e
--- /dev/null
+++ b/contracts/solidity_0.6/overriding.sol
@@ -0,0 +1,15 @@
+pragma solidity ^0.6.0;
+contract Base1
+{
+ function foo() virtual public {}
+}
+contract Base2
+{
+ function foo() virtual public {}
+}
+contract Inherited is Base1, Base2
+{
+ // Derives from multiple bases defining foo(), so we must explicitly
+ // override it
+ function foo() public override(Base1, Base2) {}
+}
diff --git a/contracts/solidity_0.6/receive.sol b/contracts/solidity_0.6/receive.sol
new file mode 100644
index 0000000000..9da8a8a1e7
--- /dev/null
+++ b/contracts/solidity_0.6/receive.sol
@@ -0,0 +1,9 @@
+pragma solidity ^0.6.0;
+// This contract keeps all Ether sent to it with no way
+// to get it back.
+contract Sink {
+ event Received(address, uint);
+ receive() external payable {
+ emit Received(msg.sender, msg.value);
+ }
+}
diff --git a/contracts/solidity_0.6/state_variable_shadowing_disabled.sol b/contracts/solidity_0.6/state_variable_shadowing_disabled.sol
new file mode 100644
index 0000000000..c628863e37
--- /dev/null
+++ b/contracts/solidity_0.6/state_variable_shadowing_disabled.sol
@@ -0,0 +1,9 @@
+pragma solidity ^0.6.0;
+contract Test {
+ address x;
+}
+contract TestOverride is Test {
+// This declaration would throw an error because its shadowing a
+// state variable already in its base inherited contract Test
+ address x;
+}
diff --git a/contracts/solidity_0.6/trycatch.sol b/contracts/solidity_0.6/trycatch.sol
new file mode 100644
index 0000000000..2a3977d830
--- /dev/null
+++ b/contracts/solidity_0.6/trycatch.sol
@@ -0,0 +1,28 @@
+pragma solidity ^0.6.0;
+interface DataFeed {
+ function getData(address token) external returns (uint value);
+}
+contract FeedConsumer {
+ DataFeed feed;
+ uint errorCount;
+ function rate(address token) public returns (uint value, bool success) {
+ // Permanently disable the mechanism if there are
+ // more than 10 errors.
+ require(errorCount < 10);
+ try feed.getData(token) returns (uint v) {
+ return (v, true);
+ } catch Error(string memory /*reason*/) {
+ // This is executed in case
+ // revert was called inside getData
+ // and a reason string was provided.
+ errorCount++;
+ return (0, false);
+ } catch (bytes memory /*lowLevelData*/) {
+ // This is executed in case revert() was used
+ // or there was a failing assertion, division
+ // by zero, etc. inside getData.
+ errorCount++;
+ return (0, false);
+ }
+ }
+}
diff --git a/contracts/tests/Inherited.go b/contracts/tests/Inherited.go
new file mode 100644
index 0000000000..76f7487234
--- /dev/null
+++ b/contracts/tests/Inherited.go
@@ -0,0 +1,43 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package tests
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/tests/contract"
+)
+
+type MyInherited struct {
+ *contract.InheritedSession
+ contractBackend bind.ContractBackend
+}
+
+func NewMyInherited(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*MyInherited, error) {
+ smartContract, err := contract.NewInherited(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+
+ return &MyInherited{
+ &contract.InheritedSession{
+ Contract: smartContract,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+func DeployMyInherited(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *MyInherited, error) {
+ contractAddr, _, _, err := contract.DeployInherited(transactOpts, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+ smartContract, err := NewMyInherited(transactOpts, contractAddr, contractBackend)
+ if err != nil {
+ return contractAddr, nil, err
+ }
+
+ return contractAddr, smartContract, nil
+}
diff --git a/contracts/tests/Inherited_test.go b/contracts/tests/Inherited_test.go
new file mode 100644
index 0000000000..a1e4a47203
--- /dev/null
+++ b/contracts/tests/Inherited_test.go
@@ -0,0 +1,43 @@
+package tests
+
+import (
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "math/big"
+ "os"
+ "testing"
+)
+
+var (
+ mainKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ mainAddr = crypto.PubkeyToAddress(mainKey.PublicKey)
+)
+
+func TestPriceFeed(t *testing.T) {
+ glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
+ glogger.Verbosity(log.LvlTrace)
+ log.Root().SetHandler(glogger)
+ common.TIPXDCXCancellationFee = big.NewInt(0)
+ // init genesis
+ contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{
+ mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))},
+ })
+ transactOpts := bind.NewKeyedTransactor(mainKey)
+ // deploy payer swap SMC
+ addr, contract, err := DeployMyInherited(transactOpts, contractBackend)
+ if err != nil {
+ t.Fatal("can't deploy smart contract: ", err)
+ }
+ fmt.Println("addr", addr.Hex())
+ tx, err := contract.Foo()
+ if err != nil {
+ t.Fatal("can't run function Foo() in smart contract: ", err)
+ }
+ fmt.Println("tx", tx)
+
+}
diff --git a/contracts/tests/contract/Inherited.go b/contracts/tests/contract/Inherited.go
new file mode 100644
index 0000000000..71b3929ed2
--- /dev/null
+++ b/contracts/tests/contract/Inherited.go
@@ -0,0 +1,559 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "strings"
+
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+)
+
+// Base1ABI is the input ABI used to generate the binding from.
+const Base1ABI = "[{\"inputs\":[],\"name\":\"foo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
+
+// Base1Bin is the compiled bytecode used for deploying new contracts.
+const Base1Bin = `0x6080604052348015600f57600080fd5b50606d80601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336035565b005b56fea2646970667358221220861aecb7678c5118a12be7047c66ea27b4e28b80d5d5d4ad1813a7b08983adb664736f6c634300060a0033`
+
+// DeployBase1 deploys a new Ethereum contract, binding an instance of Base1 to it.
+func DeployBase1(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Base1, error) {
+ parsed, err := abi.JSON(strings.NewReader(Base1ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Base1Bin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &Base1{Base1Caller: Base1Caller{contract: contract}, Base1Transactor: Base1Transactor{contract: contract}, Base1Filterer: Base1Filterer{contract: contract}}, nil
+}
+
+// Base1 is an auto generated Go binding around an Ethereum contract.
+type Base1 struct {
+ Base1Caller // Read-only binding to the contract
+ Base1Transactor // Write-only binding to the contract
+ Base1Filterer // Log filterer for contract events
+}
+
+// Base1Caller is an auto generated read-only Go binding around an Ethereum contract.
+type Base1Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base1Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type Base1Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base1Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type Base1Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base1Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type Base1Session struct {
+ Contract *Base1 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// Base1CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type Base1CallerSession struct {
+ Contract *Base1Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// Base1TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type Base1TransactorSession struct {
+ Contract *Base1Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// Base1Raw is an auto generated low-level Go binding around an Ethereum contract.
+type Base1Raw struct {
+ Contract *Base1 // Generic contract binding to access the raw methods on
+}
+
+// Base1CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type Base1CallerRaw struct {
+ Contract *Base1Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// Base1TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type Base1TransactorRaw struct {
+ Contract *Base1Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewBase1 creates a new instance of Base1, bound to a specific deployed contract.
+func NewBase1(address common.Address, backend bind.ContractBackend) (*Base1, error) {
+ contract, err := bindBase1(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &Base1{Base1Caller: Base1Caller{contract: contract}, Base1Transactor: Base1Transactor{contract: contract}, Base1Filterer: Base1Filterer{contract: contract}}, nil
+}
+
+// NewBase1Caller creates a new read-only instance of Base1, bound to a specific deployed contract.
+func NewBase1Caller(address common.Address, caller bind.ContractCaller) (*Base1Caller, error) {
+ contract, err := bindBase1(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &Base1Caller{contract: contract}, nil
+}
+
+// NewBase1Transactor creates a new write-only instance of Base1, bound to a specific deployed contract.
+func NewBase1Transactor(address common.Address, transactor bind.ContractTransactor) (*Base1Transactor, error) {
+ contract, err := bindBase1(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &Base1Transactor{contract: contract}, nil
+}
+
+// NewBase1Filterer creates a new log filterer instance of Base1, bound to a specific deployed contract.
+func NewBase1Filterer(address common.Address, filterer bind.ContractFilterer) (*Base1Filterer, error) {
+ contract, err := bindBase1(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &Base1Filterer{contract: contract}, nil
+}
+
+// bindBase1 binds a generic wrapper to an already deployed contract.
+func bindBase1(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(Base1ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Base1 *Base1Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Base1.Contract.Base1Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Base1 *Base1Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base1.Contract.Base1Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Base1 *Base1Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Base1.Contract.Base1Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Base1 *Base1CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Base1.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Base1 *Base1TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base1.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Base1 *Base1TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Base1.Contract.contract.Transact(opts, method, params...)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base1 *Base1Transactor) Foo(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base1.contract.Transact(opts, "foo")
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base1 *Base1Session) Foo() (*types.Transaction, error) {
+ return _Base1.Contract.Foo(&_Base1.TransactOpts)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base1 *Base1TransactorSession) Foo() (*types.Transaction, error) {
+ return _Base1.Contract.Foo(&_Base1.TransactOpts)
+}
+
+// Base2ABI is the input ABI used to generate the binding from.
+const Base2ABI = "[{\"inputs\":[],\"name\":\"foo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
+
+// Base2Bin is the compiled bytecode used for deploying new contracts.
+const Base2Bin = `0x6080604052348015600f57600080fd5b50606d80601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336035565b005b56fea26469706673582212205b8cfeb4357fea7b0f1d1c30727a20d5e54b63b328315e480e275c07ca89189564736f6c634300060a0033`
+
+// DeployBase2 deploys a new Ethereum contract, binding an instance of Base2 to it.
+func DeployBase2(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Base2, error) {
+ parsed, err := abi.JSON(strings.NewReader(Base2ABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Base2Bin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &Base2{Base2Caller: Base2Caller{contract: contract}, Base2Transactor: Base2Transactor{contract: contract}, Base2Filterer: Base2Filterer{contract: contract}}, nil
+}
+
+// Base2 is an auto generated Go binding around an Ethereum contract.
+type Base2 struct {
+ Base2Caller // Read-only binding to the contract
+ Base2Transactor // Write-only binding to the contract
+ Base2Filterer // Log filterer for contract events
+}
+
+// Base2Caller is an auto generated read-only Go binding around an Ethereum contract.
+type Base2Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base2Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type Base2Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base2Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type Base2Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// Base2Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type Base2Session struct {
+ Contract *Base2 // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// Base2CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type Base2CallerSession struct {
+ Contract *Base2Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// Base2TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type Base2TransactorSession struct {
+ Contract *Base2Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// Base2Raw is an auto generated low-level Go binding around an Ethereum contract.
+type Base2Raw struct {
+ Contract *Base2 // Generic contract binding to access the raw methods on
+}
+
+// Base2CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type Base2CallerRaw struct {
+ Contract *Base2Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// Base2TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type Base2TransactorRaw struct {
+ Contract *Base2Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewBase2 creates a new instance of Base2, bound to a specific deployed contract.
+func NewBase2(address common.Address, backend bind.ContractBackend) (*Base2, error) {
+ contract, err := bindBase2(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &Base2{Base2Caller: Base2Caller{contract: contract}, Base2Transactor: Base2Transactor{contract: contract}, Base2Filterer: Base2Filterer{contract: contract}}, nil
+}
+
+// NewBase2Caller creates a new read-only instance of Base2, bound to a specific deployed contract.
+func NewBase2Caller(address common.Address, caller bind.ContractCaller) (*Base2Caller, error) {
+ contract, err := bindBase2(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &Base2Caller{contract: contract}, nil
+}
+
+// NewBase2Transactor creates a new write-only instance of Base2, bound to a specific deployed contract.
+func NewBase2Transactor(address common.Address, transactor bind.ContractTransactor) (*Base2Transactor, error) {
+ contract, err := bindBase2(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &Base2Transactor{contract: contract}, nil
+}
+
+// NewBase2Filterer creates a new log filterer instance of Base2, bound to a specific deployed contract.
+func NewBase2Filterer(address common.Address, filterer bind.ContractFilterer) (*Base2Filterer, error) {
+ contract, err := bindBase2(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &Base2Filterer{contract: contract}, nil
+}
+
+// bindBase2 binds a generic wrapper to an already deployed contract.
+func bindBase2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(Base2ABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Base2 *Base2Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Base2.Contract.Base2Caller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Base2 *Base2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base2.Contract.Base2Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Base2 *Base2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Base2.Contract.Base2Transactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Base2 *Base2CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Base2.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Base2 *Base2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base2.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Base2 *Base2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Base2.Contract.contract.Transact(opts, method, params...)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base2 *Base2Transactor) Foo(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Base2.contract.Transact(opts, "foo")
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base2 *Base2Session) Foo() (*types.Transaction, error) {
+ return _Base2.Contract.Foo(&_Base2.TransactOpts)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Base2 *Base2TransactorSession) Foo() (*types.Transaction, error) {
+ return _Base2.Contract.Foo(&_Base2.TransactOpts)
+}
+
+// InheritedABI is the input ABI used to generate the binding from.
+const InheritedABI = "[{\"inputs\":[],\"name\":\"foo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
+
+// InheritedBin is the compiled bytecode used for deploying new contracts.
+const InheritedBin = `0x6080604052348015600f57600080fd5b50606d80601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336035565b005b56fea2646970667358221220bbe212c6ad2a1b1546352d1975164c6f0fb7b6d29285b29b7d444d7bc2d8198d64736f6c634300060a0033`
+
+// DeployInherited deploys a new Ethereum contract, binding an instance of Inherited to it.
+func DeployInherited(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Inherited, error) {
+ parsed, err := abi.JSON(strings.NewReader(InheritedABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(InheritedBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &Inherited{InheritedCaller: InheritedCaller{contract: contract}, InheritedTransactor: InheritedTransactor{contract: contract}, InheritedFilterer: InheritedFilterer{contract: contract}}, nil
+}
+
+// Inherited is an auto generated Go binding around an Ethereum contract.
+type Inherited struct {
+ InheritedCaller // Read-only binding to the contract
+ InheritedTransactor // Write-only binding to the contract
+ InheritedFilterer // Log filterer for contract events
+}
+
+// InheritedCaller is an auto generated read-only Go binding around an Ethereum contract.
+type InheritedCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// InheritedTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type InheritedTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// InheritedFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type InheritedFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// InheritedSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type InheritedSession struct {
+ Contract *Inherited // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// InheritedCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type InheritedCallerSession struct {
+ Contract *InheritedCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// InheritedTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type InheritedTransactorSession struct {
+ Contract *InheritedTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// InheritedRaw is an auto generated low-level Go binding around an Ethereum contract.
+type InheritedRaw struct {
+ Contract *Inherited // Generic contract binding to access the raw methods on
+}
+
+// InheritedCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type InheritedCallerRaw struct {
+ Contract *InheritedCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// InheritedTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type InheritedTransactorRaw struct {
+ Contract *InheritedTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewInherited creates a new instance of Inherited, bound to a specific deployed contract.
+func NewInherited(address common.Address, backend bind.ContractBackend) (*Inherited, error) {
+ contract, err := bindInherited(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &Inherited{InheritedCaller: InheritedCaller{contract: contract}, InheritedTransactor: InheritedTransactor{contract: contract}, InheritedFilterer: InheritedFilterer{contract: contract}}, nil
+}
+
+// NewInheritedCaller creates a new read-only instance of Inherited, bound to a specific deployed contract.
+func NewInheritedCaller(address common.Address, caller bind.ContractCaller) (*InheritedCaller, error) {
+ contract, err := bindInherited(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &InheritedCaller{contract: contract}, nil
+}
+
+// NewInheritedTransactor creates a new write-only instance of Inherited, bound to a specific deployed contract.
+func NewInheritedTransactor(address common.Address, transactor bind.ContractTransactor) (*InheritedTransactor, error) {
+ contract, err := bindInherited(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &InheritedTransactor{contract: contract}, nil
+}
+
+// NewInheritedFilterer creates a new log filterer instance of Inherited, bound to a specific deployed contract.
+func NewInheritedFilterer(address common.Address, filterer bind.ContractFilterer) (*InheritedFilterer, error) {
+ contract, err := bindInherited(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &InheritedFilterer{contract: contract}, nil
+}
+
+// bindInherited binds a generic wrapper to an already deployed contract.
+func bindInherited(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(InheritedABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Inherited *InheritedRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Inherited.Contract.InheritedCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Inherited *InheritedRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Inherited.Contract.InheritedTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Inherited *InheritedRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Inherited.Contract.InheritedTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Inherited *InheritedCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Inherited.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Inherited *InheritedTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Inherited.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Inherited *InheritedTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Inherited.Contract.contract.Transact(opts, method, params...)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Inherited *InheritedTransactor) Foo(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Inherited.contract.Transact(opts, "foo")
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Inherited *InheritedSession) Foo() (*types.Transaction, error) {
+ return _Inherited.Contract.Foo(&_Inherited.TransactOpts)
+}
+
+// Foo is a paid mutator transaction binding the contract method 0xc2985578.
+//
+// Solidity: function foo() returns()
+func (_Inherited *InheritedTransactorSession) Foo() (*types.Transaction, error) {
+ return _Inherited.Contract.Foo(&_Inherited.TransactOpts)
+}
diff --git a/contracts/tests/contract/Inherited.sol b/contracts/tests/contract/Inherited.sol
new file mode 100644
index 0000000000..1680754569
--- /dev/null
+++ b/contracts/tests/contract/Inherited.sol
@@ -0,0 +1,19 @@
+pragma solidity >=0.5.0 <0.7.0;
+
+contract Base1
+{
+ function foo() virtual public {}
+}
+
+contract Base2
+{
+ function foo() virtual public {}
+}
+
+contract Inherited is Base1, Base2
+{
+ // Derives from multiple bases defining foo(), so we must explicitly
+ // override it
+ function foo() public override(Base1, Base2) {}
+}
+
diff --git a/contracts/tests/contract/libs/SafeMath.sol b/contracts/tests/contract/libs/SafeMath.sol
new file mode 100644
index 0000000000..9c73d956f9
--- /dev/null
+++ b/contracts/tests/contract/libs/SafeMath.sol
@@ -0,0 +1,47 @@
+pragma solidity ^0.6.10;
+
+/**
+ * @title SafeMath
+ * @dev Math operations with safety checks that throw on error
+ */
+library SafeMath {
+
+ /**
+ * @dev Multiplies two numbers, throws on overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ if (a == 0) {
+ return 0;
+ }
+ uint256 c = a * b;
+ assert(c / a == b);
+ return c;
+ }
+
+ /**
+ * @dev Integer division of two numbers, truncating the quotient.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ // assert(b > 0); // Solidity automatically throws when dividing by 0
+ // uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+ return a / b;
+ }
+
+ /**
+ * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ assert(b <= a);
+ return a - b;
+ }
+
+ /**
+ * @dev Adds two numbers, throws on overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ assert(c >= a);
+ return c;
+ }
+}
diff --git a/contracts/trc21issuer/contract/TRC21.go b/contracts/trc21issuer/contract/TRC21.go
index 6f26a8eb75..f24bb3c3a5 100644
--- a/contracts/trc21issuer/contract/TRC21.go
+++ b/contracts/trc21issuer/contract/TRC21.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// ITRC21ABI is the input ABI used to generate the binding from.
diff --git a/contracts/trc21issuer/contract/TRC21Issuer.go b/contracts/trc21issuer/contract/TRC21Issuer.go
index 15381d9190..b5e584a5df 100644
--- a/contracts/trc21issuer/contract/TRC21Issuer.go
+++ b/contracts/trc21issuer/contract/TRC21Issuer.go
@@ -7,12 +7,12 @@ import (
"math/big"
"strings"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// AbstractTokenTRC21ABI is the input ABI used to generate the binding from.
diff --git a/contracts/trc21issuer/simulation/common.go b/contracts/trc21issuer/simulation/common.go
index 1ba7e4df4b..e29ef5b24e 100644
--- a/contracts/trc21issuer/simulation/common.go
+++ b/contracts/trc21issuer/simulation/common.go
@@ -1,9 +1,8 @@
package simulation
import (
+ "github.com/XinFinOrg/XDPoSChain/crypto"
"math/big"
-
- "github.com/ethereum/go-ethereum/crypto"
)
var (
diff --git a/contracts/trc21issuer/simulation/deploy/main.go b/contracts/trc21issuer/simulation/deploy/main.go
index 9a4ead716e..15cc304279 100644
--- a/contracts/trc21issuer/simulation/deploy/main.go
+++ b/contracts/trc21issuer/simulation/deploy/main.go
@@ -3,15 +3,14 @@ package main
import (
"context"
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer/simulation"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
"log"
"math/big"
"time"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer/simulation"
- "github.com/ethereum/go-ethereum/ethclient"
)
func main() {
diff --git a/contracts/trc21issuer/simulation/test/main.go b/contracts/trc21issuer/simulation/test/main.go
index 0d7d59c715..ef2eb197e8 100644
--- a/contracts/trc21issuer/simulation/test/main.go
+++ b/contracts/trc21issuer/simulation/test/main.go
@@ -4,16 +4,15 @@ import (
"context"
"encoding/json"
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer/simulation"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
"log"
"math/big"
"time"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer/simulation"
- "github.com/ethereum/go-ethereum/ethclient"
)
var (
diff --git a/contracts/trc21issuer/trc21.go b/contracts/trc21issuer/trc21.go
index 2004de9801..3d5f927692 100644
--- a/contracts/trc21issuer/trc21.go
+++ b/contracts/trc21issuer/trc21.go
@@ -1,9 +1,9 @@
package trc21issuer
import (
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer/contract"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer/contract"
"math/big"
)
diff --git a/contracts/trc21issuer/trc21issuer.go b/contracts/trc21issuer/trc21issuer.go
index 0d5d5b6dfe..2ea24fec8d 100644
--- a/contracts/trc21issuer/trc21issuer.go
+++ b/contracts/trc21issuer/trc21issuer.go
@@ -1,9 +1,9 @@
package trc21issuer
import (
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/trc21issuer/contract"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/contracts/trc21issuer/contract"
"math/big"
)
diff --git a/contracts/trc21issuer/trc21issuer_test.go b/contracts/trc21issuer/trc21issuer_test.go
index 151aa62e46..e28344caf0 100644
--- a/contracts/trc21issuer/trc21issuer_test.go
+++ b/contracts/trc21issuer/trc21issuer_test.go
@@ -1,14 +1,13 @@
package trc21issuer
import (
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
"math/big"
"testing"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
)
var (
diff --git a/contracts/utils.go b/contracts/utils.go
index 0ac7b06ec8..7179a03cf1 100644
--- a/contracts/utils.go
+++ b/contracts/utils.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -30,21 +30,21 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/XDPoS"
- "github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
- randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- stateDatabase "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/accounts"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
+ "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/contract"
+ randomizeContract "github.com/XinFinOrg/XDPoSChain/contracts/randomize/contract"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ stateDatabase "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
const (
diff --git a/contracts/utils_test.go b/contracts/utils_test.go
index 5c78bf6507..abcf84aeb3 100644
--- a/contracts/utils_test.go
+++ b/contracts/utils_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 XDCchain
+// Copyright (c) 2018 XDPoSChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
@@ -19,19 +19,18 @@ import (
"bytes"
"context"
"crypto/ecdsa"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
+ "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
"math/big"
"math/rand"
"testing"
"time"
-
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/XDPoS"
- "github.com/ethereum/go-ethereum/contracts/blocksigner"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
)
var (
diff --git a/contracts/validator/contract/XDCValidator.sol b/contracts/validator/contract/XDCValidator.sol
index 732c690420..34d8b4e51b 100644
--- a/contracts/validator/contract/XDCValidator.sol
+++ b/contracts/validator/contract/XDCValidator.sol
@@ -1,9 +1,7 @@
-
pragma solidity ^0.4.21;
import "./libs/SafeMath.sol";
-
contract XDCValidator {
using SafeMath for uint256;
@@ -12,8 +10,6 @@ contract XDCValidator {
event Propose(address _owner, address _candidate, uint256 _cap);
event Resign(address _owner, address _candidate);
event Withdraw(address _owner, uint256 _blockNumber, uint256 _cap);
- event UploadedKYC(address _owner,string kycHash);
- event InvalidatedNode(address _masternodeOwner, address[] _masternodes);
struct ValidatorState {
address owner;
@@ -31,18 +27,9 @@ contract XDCValidator {
mapping(address => ValidatorState) validatorsState;
mapping(address => address[]) voters;
-
- // Mapping structures added for KYC feature.
- mapping(address => string[]) public KYCString;
- mapping(address => uint) public invalidKYCCount;
- mapping(address => mapping(address => bool)) public hasVotedInvalid;
- mapping(address => address[]) public ownerToCandidate;
- address[] public owners;
-
address[] public candidates;
uint256 public candidateCount = 0;
- uint256 public ownerCount =0;
uint256 public minCandidateCap;
uint256 public minVoterCap;
uint256 public maxValidatorNumber;
@@ -56,16 +43,10 @@ contract XDCValidator {
}
modifier onlyValidVoterCap {
-
require(msg.value >= minVoterCap);
_;
}
- modifier onlyKYCWhitelisted {
- require(KYCString[msg.sender].length!=0 || ownerToCandidate[msg.sender].length>0);
- _;
- }
-
modifier onlyOwner(address _candidate) {
require(validatorsState[_candidate].owner == msg.sender);
_;
@@ -118,8 +99,7 @@ contract XDCValidator {
candidateWithdrawDelay = _candidateWithdrawDelay;
voterWithdrawDelay = _voterWithdrawDelay;
candidateCount = _candidates.length;
- owners.push(_firstOwner);
- ownerCount++;
+
for (uint256 i = 0; i < _candidates.length; i++) {
candidates.push(_candidates[i]);
validatorsState[_candidates[i]] = ValidatorState({
@@ -128,20 +108,11 @@ contract XDCValidator {
cap: _caps[i]
});
voters[_candidates[i]].push(_firstOwner);
- ownerToCandidate[_firstOwner].push(_candidates[i]);
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
}
}
-
- // uploadKYC : anyone can upload a KYC; its not equivalent to becoming an owner.
- function uploadKYC(string kychash) external {
- KYCString[msg.sender].push(kychash);
- emit UploadedKYC(msg.sender,kychash);
- }
-
- // propose : any non-candidate who has uploaded its KYC can become an owner by proposing a candidate.
- function propose(address _candidate) external payable onlyValidCandidateCap onlyKYCWhitelisted onlyNotCandidate(_candidate) {
+ function propose(address _candidate) external payable onlyValidCandidateCap onlyNotCandidate(_candidate) {
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
candidates.push(_candidate);
validatorsState[_candidate] = ValidatorState({
@@ -151,11 +122,6 @@ contract XDCValidator {
});
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
candidateCount = candidateCount.add(1);
- if (ownerToCandidate[msg.sender].length ==0){
- owners.push(msg.sender);
- ownerCount++;
- }
- ownerToCandidate[msg.sender].push(_candidate);
voters[_candidate].push(msg.sender);
emit Propose(msg.sender, _candidate, msg.value);
}
@@ -232,67 +198,6 @@ contract XDCValidator {
emit Resign(msg.sender, _candidate);
}
- // voteInvalidKYC : any candidate can vote for invalid KYC i.e. a particular candidate's owner has uploaded a bad KYC.
- // On securing 75% votes against an owner ( not candidate ), owner & all its candidates will lose their funds.
- function voteInvalidKYC(address _invalidCandidate) onlyValidCandidate(msg.sender) onlyValidCandidate(_invalidCandidate) public {
- address candidateOwner = getCandidateOwner(msg.sender);
- address _invalidMasternode = getCandidateOwner(_invalidCandidate);
- require(!hasVotedInvalid[candidateOwner][_invalidMasternode]);
- hasVotedInvalid[candidateOwner][_invalidMasternode] = true;
- invalidKYCCount[_invalidMasternode] += 1;
- if( invalidKYCCount[_invalidMasternode]*100/getOwnerCount() >= 75 ){
- // 75% owners say that the KYC is invalid
- address[] memory allMasternodes = new address[](candidates.length-1) ;
- uint count=0;
- for (uint i=0;i bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
+ tradingRoot, err := tradingService.GetTradingStateRoot(currentBlock, author)
+ if err != nil {
+ repair = true
+ } else {
+ if tradingService.GetStateCache() != nil {
+ _, err = tradingstate.New(tradingRoot, tradingService.GetStateCache())
+ if err != nil {
+ repair = true
+ }
+ }
+ }
+
+ if !repair {
+ lendingRoot, err := lendingService.GetLendingStateRoot(currentBlock, author)
+ if err != nil {
+ repair = true
+ } else {
+ if lendingService.GetStateCache() != nil {
+ _, err = lendingstate.New(lendingRoot, lendingService.GetStateCache())
+ if err != nil {
+ repair = true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if repair {
// Dangling block without a state associated, init from scratch
log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash())
if err := bc.repair(¤tBlock); err != nil {
@@ -351,7 +437,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
if block == nil {
return fmt.Errorf("non existent block [%x…]", hash[:4])
}
- if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil {
+ if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil {
return err
}
// If all checks out, manually set the head block
@@ -418,6 +504,45 @@ func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
return state.New(root, bc.stateCache)
}
+// OrderStateAt returns a new mutable state based on a particular point in time.
+func (bc *BlockChain) OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error) {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if ok {
+ XDCXService := engine.GetXDCXService()
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch && XDCXService != nil {
+ author, _ := bc.Engine().Author(block.Header())
+ log.Debug("OrderStateAt", "blocknumber", block.Header().Number)
+ XDCxState, err := XDCXService.GetTradingState(block, author)
+ if err == nil {
+ return XDCxState, nil
+ } else {
+ return nil, err
+ }
+ }
+ }
+ return nil, errors.New("Get XDCx state fail")
+
+}
+
+// LendingStateAt returns a new mutable state based on a particular point in time.
+func (bc *BlockChain) LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error) {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if ok {
+ lendingService := engine.GetLendingService()
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch && lendingService != nil {
+ author, _ := bc.Engine().Author(block.Header())
+ log.Debug("LendingStateAt", "blocknumber", block.Header().Number)
+ lendingState, err := lendingService.GetLendingState(block, author)
+ if err == nil {
+ return lendingState, nil
+ }
+ return nil, err
+ }
+ }
+ return nil, errors.New("Get XDCx state fail")
+
+}
+
// Reset purges the entire blockchain, restoring it to its genesis state.
func (bc *BlockChain) Reset() error {
return bc.ResetWithGenesisBlock(bc.genesisBlock)
@@ -459,9 +584,37 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
func (bc *BlockChain) repair(head **types.Block) error {
for {
// Abort if we've rewound to a head block that does have associated state
- if _, err := state.New((*head).Root(), bc.stateCache); err == nil {
+ if (common.Rewound == uint64(0)) || ((*head).Number().Uint64() < common.Rewound) {
+ if _, err := state.New((*head).Root(), bc.stateCache); err == nil {
+ log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if ok {
+ tradingService := engine.GetXDCXService()
+ lendingService := engine.GetLendingService()
+ if bc.Config().IsTIPXDCX((*head).Number()) && bc.chainConfig.XDPoS != nil && (*head).NumberU64() > bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
+ author, _ := bc.Engine().Author((*head).Header())
+ tradingRoot, err := tradingService.GetTradingStateRoot(*head, author)
+ if err == nil {
+ _, err = tradingstate.New(tradingRoot, tradingService.GetStateCache())
+ }
+ if err == nil {
+ lendingRoot, err := lendingService.GetLendingStateRoot(*head, author)
+ if err == nil {
+ _, err = lendingstate.New(lendingRoot, lendingService.GetStateCache())
+ if err == nil {
+ return nil
+ }
+ }
+ }
+ } else {
+ return nil
+ }
+ } else {
+ return nil
+ }
+ }
+ } else {
log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
- return nil
}
// Otherwise rewind one block and recheck state availability there
(*head) = bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
@@ -518,8 +671,10 @@ func (bc *BlockChain) insert(block *types.Block) {
// save cache BlockSigners
if bc.chainConfig.XDPoS != nil && !bc.chainConfig.IsTIPSigning(block.Number()) {
- engine := bc.Engine().(*XDPoS.XDPoS)
- engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if ok {
+ engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
+ }
}
// If the block is better than our head or is on a different chain, force update heads
@@ -580,21 +735,36 @@ func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
return ok
}
-// HasState checks if state trie is fully present in the database or not.
-func (bc *BlockChain) HasState(hash common.Hash) bool {
- _, err := bc.stateCache.OpenTrie(hash)
- return err == nil
+// HasFullState checks if state trie is fully present in the database or not.
+func (bc *BlockChain) HasFullState(block *types.Block) bool {
+ _, err := bc.stateCache.OpenTrie(block.Root())
+ if err != nil {
+ return false
+ }
+ engine, _ := bc.Engine().(*XDPoS.XDPoS)
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && engine != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ tradingService := engine.GetXDCXService()
+ lendingService := engine.GetLendingService()
+ author, _ := bc.Engine().Author(block.Header())
+ if tradingService != nil && !tradingService.HasTradingState(block, author) {
+ return false
+ }
+ if lendingService != nil && !lendingService.HasLendingState(block, author) {
+ return false
+ }
+ }
+ return true
}
-// HasBlockAndState checks if a block and associated state trie is fully present
+// HasBlockAndFullState checks if a block and associated state trie is fully present
// in the database or not, caching it if present.
-func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
+func (bc *BlockChain) HasBlockAndFullState(hash common.Hash, number uint64) bool {
// Check first that the block itself is known
block := bc.GetBlock(hash, number)
if block == nil {
return false
}
- return bc.HasState(block.Root())
+ return bc.HasFullState(block)
}
// GetBlock retrieves a block from the database by hash and number,
@@ -691,6 +861,84 @@ func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
return bc.stateCache.TrieDB().Node(hash)
}
+func (bc *BlockChain) SaveData() {
+ bc.wg.Add(1)
+ defer bc.wg.Done()
+ // Make sure no inconsistent state is leaked during insertion
+ bc.mu.Lock()
+ defer bc.mu.Unlock()
+ // Ensure the state of a recent block is also stored to disk before exiting.
+ // We're writing three different states to catch different restart scenarios:
+ // - HEAD: So we don't need to reprocess any blocks in the general case
+ // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
+ // - HEAD-127: So we have a hard limit on the number of blocks reexecuted
+ if !bc.cacheConfig.Disabled {
+ var tradingTriedb *trie.Database
+ var lendingTriedb *trie.Database
+ engine, _ := bc.Engine().(*XDPoS.XDPoS)
+ triedb := bc.stateCache.TrieDB()
+ var tradingService XDPoS.TradingService
+ var lendingService XDPoS.LendingService
+ if bc.Config().IsTIPXDCX(bc.CurrentBlock().Number()) && bc.chainConfig.XDPoS != nil && bc.CurrentBlock().NumberU64() > bc.chainConfig.XDPoS.Epoch && engine != nil {
+ tradingService = engine.GetXDCXService()
+ if tradingService != nil && tradingService.GetStateCache() != nil {
+ tradingTriedb = tradingService.GetStateCache().TrieDB()
+ }
+ lendingService = engine.GetLendingService()
+ if lendingService != nil && lendingService.GetStateCache() != nil {
+ lendingTriedb = lendingService.GetStateCache().TrieDB()
+ }
+ }
+ for _, offset := range []uint64{0, 1, triesInMemory - 1} {
+ if number := bc.CurrentBlock().NumberU64(); number > offset {
+ recent := bc.GetBlockByNumber(number - offset)
+
+ log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
+ if err := triedb.Commit(recent.Root(), true); err != nil {
+ log.Error("Failed to commit recent state trie", "err", err)
+ }
+ if bc.Config().IsTIPXDCX(recent.Number()) && bc.chainConfig.XDPoS != nil && recent.NumberU64() > bc.chainConfig.XDPoS.Epoch && engine != nil {
+ author, _ := bc.Engine().Author(recent.Header())
+ if tradingService != nil {
+ tradingRoot, _ := tradingService.GetTradingStateRoot(recent, author)
+ if !common.EmptyHash(tradingRoot) && tradingTriedb != nil {
+ if err := tradingTriedb.Commit(tradingRoot, true); err != nil {
+ log.Error("Failed to commit trading state recent state trie", "err", err)
+ }
+ }
+ }
+ if lendingService != nil {
+ lendingRoot, _ := lendingService.GetLendingStateRoot(recent, author)
+ if !common.EmptyHash(lendingRoot) && lendingTriedb != nil {
+ if err := lendingTriedb.Commit(lendingRoot, true); err != nil {
+ log.Error("Failed to commit lending state recent state trie", "err", err)
+ }
+ }
+ }
+ }
+ }
+ }
+ for !bc.triegc.Empty() {
+ triedb.Dereference(bc.triegc.PopItem().(common.Hash))
+ }
+ if tradingTriedb != nil && lendingTriedb != nil {
+ if tradingService.GetTriegc() != nil {
+ for !tradingService.GetTriegc().Empty() {
+ tradingTriedb.Dereference(tradingService.GetTriegc().PopItem().(common.Hash))
+ }
+ }
+ if lendingService.GetTriegc() != nil {
+ for !lendingService.GetTriegc().Empty() {
+ lendingTriedb.Dereference(lendingService.GetTriegc().PopItem().(common.Hash))
+ }
+ }
+ }
+ if size, _ := triedb.Size(); size != 0 {
+ log.Error("Dangling trie nodes after full cleanup")
+ }
+ }
+}
+
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
func (bc *BlockChain) Stop() {
@@ -701,33 +949,8 @@ func (bc *BlockChain) Stop() {
bc.scope.Close()
close(bc.quit)
atomic.StoreInt32(&bc.procInterrupt, 1)
-
bc.wg.Wait()
-
- // Ensure the state of a recent block is also stored to disk before exiting.
- // We're writing three different states to catch different restart scenarios:
- // - HEAD: So we don't need to reprocess any blocks in the general case
- // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
- // - HEAD-127: So we have a hard limit on the number of blocks reexecuted
- if !bc.cacheConfig.Disabled {
- triedb := bc.stateCache.TrieDB()
- for _, offset := range []uint64{0, 1, triesInMemory - 1} {
- if number := bc.CurrentBlock().NumberU64(); number > offset {
- recent := bc.GetBlockByNumber(number - offset)
-
- log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
- if err := triedb.Commit(recent.Root(), true); err != nil {
- log.Error("Failed to commit recent state trie", "err", err)
- }
- }
- }
- for !bc.triegc.Empty() {
- triedb.Dereference(bc.triegc.PopItem().(common.Hash), common.Hash{})
- }
- if size := triedb.Size(); size != 0 {
- log.Error("Dangling trie nodes after full cleanup")
- }
- }
+ bc.SaveData()
log.Info("Blockchain manager stopped")
}
@@ -932,7 +1155,7 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e
}
// WriteBlockWithState writes the block and all associated state to the database.
-func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) {
+func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (status WriteStatus, err error) {
bc.wg.Add(1)
defer bc.wg.Done()
@@ -962,45 +1185,112 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
if err != nil {
return NonStatTy, err
}
+ tradingRoot := common.Hash{}
+ if tradingState != nil {
+ tradingRoot, err = tradingState.Commit()
+ if err != nil {
+ return NonStatTy, err
+ }
+ }
+ lendingRoot := common.Hash{}
+ if lendingState != nil {
+ lendingRoot, err = lendingState.Commit()
+ if err != nil {
+ return NonStatTy, err
+ }
+ }
+ engine, _ := bc.Engine().(*XDPoS.XDPoS)
+ var tradingTrieDb *trie.Database
+ var tradingService XDPoS.TradingService
+ var lendingTrieDb *trie.Database
+ var lendingService XDPoS.LendingService
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch && engine != nil {
+ tradingService = engine.GetXDCXService()
+ if tradingService != nil {
+ tradingTrieDb = tradingService.GetStateCache().TrieDB()
+ }
+ lendingService = engine.GetLendingService()
+ if lendingService != nil {
+ lendingTrieDb = lendingService.GetStateCache().TrieDB()
+ }
+ }
triedb := bc.stateCache.TrieDB()
-
// If we're running an archive node, always flush
if bc.cacheConfig.Disabled {
if err := triedb.Commit(root, false); err != nil {
return NonStatTy, err
}
+ if tradingTrieDb != nil {
+ if err := tradingTrieDb.Commit(tradingRoot, false); err != nil {
+ return NonStatTy, err
+ }
+ }
+ if lendingTrieDb != nil {
+ if err := lendingTrieDb.Commit(lendingRoot, false); err != nil {
+ return NonStatTy, err
+ }
+ }
} else {
// Full but not archive node, do proper garbage collection
triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive
bc.triegc.Push(root, -float32(block.NumberU64()))
-
+ if tradingTrieDb != nil {
+ tradingTrieDb.Reference(tradingRoot, common.Hash{})
+ }
+ if tradingService != nil {
+ tradingService.GetTriegc().Push(tradingRoot, -float32(block.NumberU64()))
+ }
+ if lendingTrieDb != nil {
+ lendingTrieDb.Reference(lendingRoot, common.Hash{})
+ }
+ if lendingService != nil {
+ lendingService.GetTriegc().Push(lendingRoot, -float32(block.NumberU64()))
+ }
if current := block.NumberU64(); current > triesInMemory {
// Find the next state trie we need to commit
- header := bc.GetHeaderByNumber(current - triesInMemory)
- chosen := header.Number.Uint64()
-
+ chosen := current - triesInMemory
+ oldTradingRoot := common.Hash{}
+ oldLendingRoot := common.Hash{}
// Only write to disk if we exceeded our memory allowance *and* also have at
// least a given number of tries gapped.
+ //
+ //if tradingTrieDb != nil {
+ // size = size + tradingTrieDb.Size()
+ //}
+ //if lendingTrieDb != nil {
+ // size = size + lendingTrieDb.Size()
+ //}
var (
- size = triedb.Size()
- limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024
+ nodes, imgs = triedb.Size()
+ limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024
)
- if size > limit || bc.gcproc > bc.cacheConfig.TrieTimeLimit {
- // If we're exceeding limits but haven't reached a large enough memory gap,
- // warn the user that the system is becoming unstable.
- if chosen < lastWrite+triesInMemory {
- switch {
- case size >= 2*limit:
- log.Warn("State memory usage too high, committing", "size", size, "limit", limit, "optimum", float64(chosen-lastWrite)/triesInMemory)
- case bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit:
+ if nodes > limit || imgs > 4*1024*1024 {
+ triedb.Cap(limit - ethdb.IdealBatchSize)
+ }
+ if bc.gcproc > bc.cacheConfig.TrieTimeLimit || chosen > lastWrite+triesInMemory {
+ // If the header is missing (canonical chain behind), we're reorging a low
+ // diff sidechain. Suspend committing until this operation is completed.
+ header := bc.GetHeaderByNumber(chosen)
+ if header == nil {
+ log.Warn("Reorg in progress, trie commit postponed", "number", chosen)
+ } else {
+ // If we're exceeding limits but haven't reached a large enough memory gap,
+ // warn the user that the system is becoming unstable.
+ if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit {
log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory)
}
- }
- // If optimum or critical limits reached, write to disk
- if chosen >= lastWrite+triesInMemory || size >= 2*limit || bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit {
+ // Flush an entire trie and restart the counters
triedb.Commit(header.Root, true)
lastWrite = chosen
bc.gcproc = 0
+ if tradingTrieDb != nil && lendingTrieDb != nil {
+ b := bc.GetBlock(header.Hash(), current-triesInMemory)
+ author, _ := bc.Engine().Author(b.Header())
+ oldTradingRoot, _ = tradingService.GetTradingStateRoot(b, author)
+ oldLendingRoot, _ = lendingService.GetLendingStateRoot(b, author)
+ tradingTrieDb.Commit(oldTradingRoot, true)
+ lendingTrieDb.Commit(oldLendingRoot, true)
+ }
}
}
// Garbage collect anything below our required write retention
@@ -1010,7 +1300,27 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
bc.triegc.Push(root, number)
break
}
- triedb.Dereference(root.(common.Hash), common.Hash{})
+ triedb.Dereference(root.(common.Hash))
+ }
+ if tradingService != nil {
+ for !tradingService.GetTriegc().Empty() {
+ tradingRoot, number := tradingService.GetTriegc().Pop()
+ if uint64(-number) > chosen {
+ tradingService.GetTriegc().Push(tradingRoot, number)
+ break
+ }
+ tradingTrieDb.Dereference(tradingRoot.(common.Hash))
+ }
+ }
+ if lendingService != nil {
+ for !lendingService.GetTriegc().Empty() {
+ lendingRoot, number := lendingService.GetTriegc().Pop()
+ if uint64(-number) > chosen {
+ lendingService.GetTriegc().Push(lendingRoot, number)
+ break
+ }
+ lendingTrieDb.Dereference(lendingRoot.(common.Hash))
+ }
}
}
}
@@ -1055,8 +1365,10 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
}
// save cache BlockSigners
if bc.chainConfig.XDPoS != nil && bc.chainConfig.IsTIPSigning(block.Number()) {
- engine := bc.Engine().(*XDPoS.XDPoS)
- engine.CacheSigner(block.Header().Hash(), block.Transactions())
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if ok {
+ engine.CacheSigner(block.Header().Hash(), block.Transactions())
+ }
}
bc.futureBlocks.Remove(block.Hash())
return status, nil
@@ -1078,6 +1390,8 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
// only reason this method exists as a separate one is to make locking cleaner
// with deferred statements.
func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) {
+ engine, _ := bc.Engine().(*XDPoS.XDPoS)
+
// Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ {
if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() {
@@ -1177,7 +1491,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
var winner []*types.Block
parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
- for !bc.HasState(parent.Root()) {
+ for !bc.HasFullState(parent) {
winner = append(winner, parent)
parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
}
@@ -1211,9 +1525,109 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
if err != nil {
return i, events, coalescedLogs, err
}
+ author, err := bc.Engine().Author(block.Header()) // Ignore error, we're past header validation
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ parentAuthor, _ := bc.Engine().Author(parent.Header())
+ // clear the previous dry-run cache
+ var tradingState *tradingstate.TradingStateDB
+ var lendingState *lendingstate.LendingStateDB
+ var tradingService XDPoS.TradingService
+ var lendingService XDPoS.LendingService
+ isSDKNode := false
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && engine != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ tradingService = engine.GetXDCXService()
+ lendingService = engine.GetLendingService()
+ if tradingService != nil && lendingService != nil {
+ isSDKNode = tradingService.IsSDKNode()
+ txMatchBatchData, err := ExtractTradingTransactions(block.Transactions())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ tradingState, err = tradingService.GetTradingState(parent, parentAuthor)
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ lendingState, err = lendingService.GetLendingState(parent, parentAuthor)
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 {
+ if err := tradingService.UpdateMediumPriceBeforeEpoch(block.NumberU64()/bc.chainConfig.XDPoS.Epoch, tradingState, statedb); err != nil {
+ return i, events, coalescedLogs, err
+ }
+ } else {
+ for _, txMatchBatch := range txMatchBatchData {
+ log.Debug("Verify matching transaction", "txHash", txMatchBatch.TxHash.Hex())
+ err := bc.Validator().ValidateTradingOrder(statedb, tradingState, txMatchBatch, author, block.Header())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ }
+ //
+ batches, err := ExtractLendingTransactions(block.Transactions())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ for _, batch := range batches {
+ log.Debug("Verify matching transaction", "txHash", batch.TxHash.Hex())
+ err := bc.Validator().ValidateLendingOrder(statedb, lendingState, tradingState, batch, author, block.Header())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ }
+ // liquidate / finalize open lendingTrades
+ if block.Number().Uint64()%bc.chainConfig.XDPoS.Epoch == common.LiquidateLendingTradeBlock {
+ finalizedTrades := map[common.Hash]*lendingstate.LendingTrade{}
+ finalizedTrades, _, _, _, _, err = lendingService.ProcessLiquidationData(block.Header(), bc, statedb, tradingState, lendingState)
+ if err != nil {
+ return i, events, coalescedLogs, fmt.Errorf("failed to ProcessLiquidationData. Err: %v ", err)
+ }
+ if isSDKNode {
+ finalizedTx := lendingstate.FinalizedResult{}
+ if finalizedTx, err = ExtractLendingFinalizedTradeTransactions(block.Transactions()); err != nil {
+ return i, events, coalescedLogs, err
+ }
+ bc.AddFinalizedTrades(finalizedTx.TxHash, finalizedTrades)
+ }
+ }
+ }
+ //check
+ if tradingState != nil && tradingService != nil {
+ gotRoot := tradingState.IntermediateRoot()
+ expectRoot, _ := tradingService.GetTradingStateRoot(block, author)
+ parentRoot, _ := tradingService.GetTradingStateRoot(parent, parentAuthor)
+ if gotRoot != expectRoot {
+ err = fmt.Errorf("invalid XDCx trading state merke trie got : %s , expect : %s ,parent : %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ log.Debug("XDCX Trading State Root", "number", block.NumberU64(), "parent", parentRoot.Hex(), "nextRoot", expectRoot.Hex())
+ }
+ if lendingState != nil && tradingState != nil {
+ gotRoot := lendingState.IntermediateRoot()
+ expectRoot, _ := lendingService.GetLendingStateRoot(block, author)
+ parentRoot, _ := lendingService.GetLendingStateRoot(parent, parentAuthor)
+ if gotRoot != expectRoot {
+ err = fmt.Errorf("invalid lending state merke trie got : %s , expect : %s , parent :%s ", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
+ bc.reportBlock(block, nil, err)
+ return i, events, coalescedLogs, err
+ }
+ log.Debug("XDCX Lending State Root", "number", block.NumberU64(), "parent", parentRoot.Hex(), "nextRoot", expectRoot.Hex())
+ }
+ }
+ }
feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root(), statedb)
// Process block using the parent state as reference point.
- receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig, feeCapacity)
+ receipts, logs, usedGas, err := bc.processor.Process(block, statedb, tradingState, bc.vmConfig, feeCapacity)
if err != nil {
bc.reportBlock(block, receipts, err)
return i, events, coalescedLogs, err
@@ -1225,9 +1639,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
return i, events, coalescedLogs, err
}
proctime := time.Since(bstart)
-
// Write the block to the chain and get the status.
- status, err := bc.WriteBlockWithState(block, receipts, statedb)
+ status, err := bc.WriteBlockWithState(block, receipts, statedb, tradingState, lendingState)
if err != nil {
return i, events, coalescedLogs, err
}
@@ -1260,6 +1673,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
// Only count canonical blocks for GC processing time
bc.gcproc += proctime
bc.UpdateBlocksHashCache(block)
+ if bc.chainConfig.IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ bc.logExchangeData(block)
+ bc.logLendingData(block)
+ }
case SideStatTy:
log.Debug("Inserted forked block from downloader", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), "elapsed",
common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()))
@@ -1270,11 +1687,13 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
}
stats.processed++
stats.usedGas += usedGas
- stats.report(chain, i, bc.stateCache.TrieDB().Size())
+ dirty, _ := bc.stateCache.TrieDB().Size()
+ stats.report(chain, i, dirty)
if bc.chainConfig.XDPoS != nil {
// epoch block
if (chain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 {
CheckpointCh <- 1
+
}
// prepare set of masternodes for the next epoch
if (chain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap) {
@@ -1374,7 +1793,7 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
var winner []*types.Block
parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
- for !bc.HasState(parent.Root()) {
+ for !bc.HasFullState(parent) {
winner = append(winner, parent)
parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
}
@@ -1398,9 +1817,108 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
if err != nil {
return nil, err
}
+ engine, _ := bc.Engine().(*XDPoS.XDPoS)
+ author, err := bc.Engine().Author(block.Header()) // Ignore error, we're past header validation
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ parentAuthor, _ := bc.Engine().Author(parent.Header())
+
+ var tradingState *tradingstate.TradingStateDB
+ var lendingState *lendingstate.LendingStateDB
+ var tradingService XDPoS.TradingService
+ var lendingService XDPoS.LendingService
+ isSDKNode := false
+ if bc.Config().IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && engine != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ tradingService = engine.GetXDCXService()
+ lendingService = engine.GetLendingService()
+ if tradingService != nil && lendingService != nil {
+ isSDKNode = tradingService.IsSDKNode()
+ tradingState, err = tradingService.GetTradingState(parent, parentAuthor)
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ lendingState, err = lendingService.GetLendingState(parent, parentAuthor)
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 {
+ if err := tradingService.UpdateMediumPriceBeforeEpoch(block.NumberU64()/bc.chainConfig.XDPoS.Epoch, tradingState, statedb); err != nil {
+ return nil, err
+ }
+ } else {
+ txMatchBatchData, err := ExtractTradingTransactions(block.Transactions())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ for _, txMatchBatch := range txMatchBatchData {
+ log.Debug("Verify matching transaction", "txHash", txMatchBatch.TxHash.Hex())
+ err := bc.Validator().ValidateTradingOrder(statedb, tradingState, txMatchBatch, author, block.Header())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ }
+ batches, err := ExtractLendingTransactions(block.Transactions())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ for _, batch := range batches {
+ log.Debug("Lending Verify matching transaction", "txHash", batch.TxHash.Hex())
+ err := bc.Validator().ValidateLendingOrder(statedb, lendingState, tradingState, batch, author, block.Header())
+ if err != nil {
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ }
+ // liquidate / finalize open lendingTrades
+ if block.Number().Uint64()%bc.chainConfig.XDPoS.Epoch == common.LiquidateLendingTradeBlock {
+ finalizedTrades := map[common.Hash]*lendingstate.LendingTrade{}
+ finalizedTrades, _, _, _, _, err = lendingService.ProcessLiquidationData(block.Header(), bc, statedb, tradingState, lendingState)
+ if err != nil {
+ return nil, fmt.Errorf("failed to ProcessLiquidationData. Err: %v ", err)
+ }
+ if isSDKNode {
+ finalizedTx := lendingstate.FinalizedResult{}
+ if finalizedTx, err = ExtractLendingFinalizedTradeTransactions(block.Transactions()); err != nil {
+ return nil, err
+ }
+ bc.AddFinalizedTrades(finalizedTx.TxHash, finalizedTrades)
+ }
+ }
+ }
+ if tradingState != nil && tradingService != nil {
+ gotRoot := tradingState.IntermediateRoot()
+ expectRoot, _ := tradingService.GetTradingStateRoot(block, author)
+ parentRoot, _ := tradingService.GetTradingStateRoot(parent, parentAuthor)
+ if gotRoot != expectRoot {
+ err = fmt.Errorf("invalid XDCx trading state merke trie got : %s , expect : %s ,parent : %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ log.Debug("XDCX Trading State Root", "number", block.NumberU64(), "parent", parentRoot.Hex(), "nextRoot", expectRoot.Hex())
+ }
+ if lendingState != nil && tradingState != nil {
+ gotRoot := lendingState.IntermediateRoot()
+ expectRoot, _ := lendingService.GetLendingStateRoot(block, author)
+ parentRoot, _ := lendingService.GetLendingStateRoot(parent, parentAuthor)
+ if gotRoot != expectRoot {
+ err = fmt.Errorf("invalid lending state merke trie got : %s , expect : %s , parent : %s ", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
+ bc.reportBlock(block, nil, err)
+ return nil, err
+ }
+ log.Debug("XDCX Lending State Root", "number", block.NumberU64(), "parent", parentRoot.Hex(), "nextRoot", expectRoot.Hex())
+ }
+ }
+ }
feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root(), statedb)
// Process block using the parent state as reference point.
- receipts, logs, usedGas, err := bc.processor.ProcessBlockNoValidator(calculatedBlock, statedb, bc.vmConfig, feeCapacity)
+ receipts, logs, usedGas, err := bc.processor.ProcessBlockNoValidator(calculatedBlock, statedb, tradingState, bc.vmConfig, feeCapacity)
process := time.Since(bstart)
if err != nil {
if err != ErrStopPreparingBlock {
@@ -1417,7 +1935,7 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
proctime := time.Since(bstart)
log.Debug("Calculate new block", "number", block.Number(), "hash", block.Hash(), "uncles", len(block.Uncles()),
"txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)), "process", process)
- return &ResultProcessBlock{receipts: receipts, logs: logs, state: statedb, proctime: proctime, usedGas: usedGas}, nil
+ return &ResultProcessBlock{receipts: receipts, logs: logs, state: statedb, tradingState: tradingState, lendingState: lendingState, proctime: proctime, usedGas: usedGas}, nil
}
// UpdateBlocksHashCache update BlocksHashCache by block number
@@ -1464,10 +1982,10 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
// Write the block to the chain and get the status.
bc.chainmu.Lock()
defer bc.chainmu.Unlock()
- if bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
+ if bc.HasBlockAndFullState(block.Hash(), block.NumberU64()) {
return events, coalescedLogs, nil
}
- status, err := bc.WriteBlockWithState(block, result.receipts, result.state)
+ status, err := bc.WriteBlockWithState(block, result.receipts, result.state, result.tradingState, result.lendingState)
if err != nil {
return events, coalescedLogs, err
@@ -1492,14 +2010,16 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
case CanonStatTy:
log.Debug("Inserted new block from fetcher", "number", block.Number(), "hash", block.Hash(), "uncles", len(block.Uncles()),
"txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(block.ReceivedAt)))
-
coalescedLogs = append(coalescedLogs, result.logs...)
events = append(events, ChainEvent{block, block.Hash(), result.logs})
// Only count canonical blocks for GC processing time
bc.gcproc += result.proctime
-
bc.UpdateBlocksHashCache(block)
+ if bc.chainConfig.IsTIPXDCX(block.Number()) && bc.chainConfig.XDPoS != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ bc.logExchangeData(block)
+ bc.logLendingData(block)
+ }
case SideStatTy:
log.Debug("Inserted forked block from fetcher", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), "elapsed",
common.PrettyDuration(time.Since(block.ReceivedAt)), "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()))
@@ -1511,11 +2031,13 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
}
stats.processed++
stats.usedGas += result.usedGas
- stats.report(types.Blocks{block}, 0, bc.stateCache.TrieDB().Size())
- if status == CanonStatTy && bc.chainConfig.XDPoS != nil {
+ dirty, _ := bc.stateCache.TrieDB().Size()
+ stats.report(types.Blocks{block}, 0, dirty)
+ if bc.chainConfig.XDPoS != nil {
// epoch block
if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 {
CheckpointCh <- 1
+
}
// prepare set of masternodes for the next epoch
if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap) {
@@ -1689,7 +2211,9 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
}
}()
}
-
+ if bc.chainConfig.IsTIPXDCX(commonBlock.Number()) && bc.chainConfig.XDPoS != nil && commonBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch {
+ bc.reorgTxMatches(deletedTxs, newChain)
+ }
return nil
}
@@ -1919,10 +2443,10 @@ func (bc *BlockChain) GetClient() (*ethclient.Client, error) {
}
func (bc *BlockChain) UpdateM1() error {
- if bc.Config().XDPoS == nil {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if bc.Config().XDPoS == nil || !ok {
return ErrNotXDPoS
}
- engine := bc.Engine().(*XDPoS.XDPoS)
log.Info("It's time to update new set of masternodes for the next epoch...")
// get masternodes information from smart contract
client, err := bc.GetClient()
@@ -1936,18 +2460,26 @@ func (bc *BlockChain) UpdateM1() error {
}
opts := new(bind.CallOpts)
- var candidates []common.Address
+ // var candidates []common.Address
+ // // get candidates from slot of stateDB
+ // // if can't get anything, request from contracts
+ // stateDB, err := bc.State()
+ // if err != nil {
- // get candidates from slot of stateDB
- // if can't get anything, request from contracts
- stateDB, err := bc.State()
+ // candidates, err = validator.GetCandidates(opts)
+ // if err != nil {
+
+ // return err
+ // }
+ // } else {
+
+ // candidates = state.GetCandidates(stateDB)
+
+ // }
+
+ candidates, err := validator.GetCandidates(opts)
if err != nil {
- candidates, err = validator.GetCandidates(opts)
- if err != nil {
- return err
- }
- } else {
- candidates = state.GetCandidates(stateDB)
+ return err
}
var ms []XDPoS.Masternode
@@ -1957,7 +2489,7 @@ func (bc *BlockChain) UpdateM1() error {
return err
}
//TODO: smart contract shouldn't return "0x0000000000000000000000000000000000000000"
- if candidate.String() != "0x0000000000000000000000000000000000000000" {
+ if candidate.String() != "xdc0000000000000000000000000000000000000000" {
ms = append(ms, XDPoS.Masternode{Address: candidate, Stake: v})
}
}
@@ -1973,8 +2505,20 @@ func (bc *BlockChain) UpdateM1() error {
log.Info("", "address", m.Address.String(), "stake", m.Stake)
}
// update masternodes
+
log.Info("Updating new set of masternodes")
- if len(ms) > common.MaxMasternodes {
+ // get block header
+ header := bc.CurrentHeader()
+ var maxMasternodes int
+ // check if block number is increase ms checkpoint
+ if bc.chainConfig.IsTIPIncreaseMasternodes(header.Number) {
+ // using new masterndoes
+ maxMasternodes = common.MaxMasternodesV2
+ } else {
+ // using old masterndoes
+ maxMasternodes = common.MaxMasternodes
+ }
+ if len(ms) > maxMasternodes {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms[:common.MaxMasternodes])
} else {
err = engine.UpdateMasternodes(bc, bc.CurrentHeader(), ms)
@@ -1986,3 +2530,197 @@ func (bc *BlockChain) UpdateM1() error {
}
return nil
}
+
+func (bc *BlockChain) logExchangeData(block *types.Block) {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if !ok || engine == nil {
+ return
+ }
+ XDCXService := engine.GetXDCXService()
+ if XDCXService == nil || !XDCXService.IsSDKNode() {
+ return
+ }
+ txMatchBatchData, err := ExtractTradingTransactions(block.Transactions())
+ if err != nil {
+ log.Crit("failed to extract matching transaction", "err", err)
+ return
+ }
+ if len(txMatchBatchData) == 0 {
+ return
+ }
+ currentState, err := bc.State()
+ if err != nil {
+ log.Crit("logExchangeData: failed to get current state", "err", err)
+ return
+ }
+ start := time.Now()
+ defer func() {
+ //The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns
+ // That's why we should put this log statement in an anonymous function
+ log.Debug("logExchangeData takes", "time", common.PrettyDuration(time.Since(start)), "blockNumber", block.NumberU64())
+ }()
+
+ for _, txMatchBatch := range txMatchBatchData {
+ dirtyOrderCount := uint64(0)
+ for _, txMatch := range txMatchBatch.Data {
+ var (
+ takerOrderInTx *tradingstate.OrderItem
+ trades []map[string]string
+ rejectedOrders []*tradingstate.OrderItem
+ )
+
+ if takerOrderInTx, err = txMatch.DecodeOrder(); err != nil {
+ log.Crit("SDK node decode takerOrderInTx failed", "txDataMatch", txMatch)
+ return
+ }
+ cacheKey := crypto.Keccak256Hash(txMatchBatch.TxHash.Bytes(), tradingstate.GetMatchingResultCacheKey(takerOrderInTx).Bytes())
+ // getTrades from cache
+ resultTrades, ok := bc.resultTrade.Get(cacheKey)
+ if ok && resultTrades != nil {
+ trades = resultTrades.([]map[string]string)
+ }
+
+ // getRejectedOrder from cache
+ rejected, ok := bc.rejectedOrders.Get(cacheKey)
+ if ok && rejected != nil {
+ rejectedOrders = rejected.([]*tradingstate.OrderItem)
+ }
+
+ txMatchTime := time.Unix(block.Header().Time.Int64(), 0).UTC()
+ if err := XDCXService.SyncDataToSDKNode(takerOrderInTx, txMatchBatch.TxHash, txMatchTime, currentState, trades, rejectedOrders, &dirtyOrderCount); err != nil {
+ log.Crit("failed to SyncDataToSDKNode ", "blockNumber", block.Number(), "err", err)
+ return
+ }
+ }
+ }
+}
+
+func (bc *BlockChain) reorgTxMatches(deletedTxs types.Transactions, newChain types.Blocks) {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if !ok || engine == nil {
+ return
+ }
+ XDCXService := engine.GetXDCXService()
+ lendingService := engine.GetLendingService()
+ if XDCXService == nil || !XDCXService.IsSDKNode() {
+ return
+ }
+ start := time.Now()
+ defer func() {
+ //The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns
+ // That's why we should put this log statement in an anonymous function
+ log.Debug("reorgTxMatches takes", "time", common.PrettyDuration(time.Since(start)))
+ }()
+ for _, deletedTx := range deletedTxs {
+ if deletedTx.IsTradingTransaction() {
+ log.Debug("Rollback reorg txMatch", "txhash", deletedTx.Hash())
+ if err := XDCXService.RollbackReorgTxMatch(deletedTx.Hash()); err != nil {
+ log.Crit("Reorg trading failed", "err", err, "hash", deletedTx.Hash())
+ }
+ }
+ if lendingService != nil && (deletedTx.IsLendingTransaction() || deletedTx.IsLendingFinalizedTradeTransaction()) {
+ log.Debug("Rollback reorg lendingItem", "txhash", deletedTx.Hash())
+ if err := lendingService.RollbackLendingData(deletedTx.Hash()); err != nil {
+ log.Crit("Reorg lending failed", "err", err, "hash", deletedTx.Hash())
+ }
+ }
+ }
+
+ // apply new chain
+ for i := len(newChain) - 1; i >= 0; i-- {
+ bc.logExchangeData(newChain[i])
+ bc.logLendingData(newChain[i])
+ }
+}
+
+func (bc *BlockChain) logLendingData(block *types.Block) {
+ engine, ok := bc.Engine().(*XDPoS.XDPoS)
+ if !ok || engine == nil {
+ return
+ }
+ XDCXService := engine.GetXDCXService()
+ if XDCXService == nil || !XDCXService.IsSDKNode() {
+ return
+ }
+ lendingService := engine.GetLendingService()
+ if lendingService == nil {
+ return
+ }
+ batches, err := ExtractLendingTransactions(block.Transactions())
+ if err != nil {
+ log.Crit("failed to extract lending transaction", "err", err)
+ }
+ start := time.Now()
+ defer func() {
+ //The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns
+ // That's why we should put this log statement in an anonymous function
+ log.Debug("logLendingData takes", "time", common.PrettyDuration(time.Since(start)), "blockNumber", block.NumberU64())
+ }()
+
+ for _, batch := range batches {
+
+ dirtyOrderCount := uint64(0)
+ for _, item := range batch.Data {
+ var (
+ trades []*lendingstate.LendingTrade
+ rejectedOrders []*lendingstate.LendingItem
+ )
+ // getTrades from cache
+ resultLendingTrades, ok := bc.resultLendingTrade.Get(crypto.Keccak256Hash(batch.TxHash.Bytes(), lendingstate.GetLendingCacheKey(item).Bytes()))
+
+ if ok && resultLendingTrades != nil {
+ trades = resultLendingTrades.([]*lendingstate.LendingTrade)
+ }
+
+ // getRejectedOrder from cache
+ rejected, ok := bc.rejectedLendingItem.Get(crypto.Keccak256Hash(batch.TxHash.Bytes(), lendingstate.GetLendingCacheKey(item).Bytes()))
+ if ok && rejected != nil {
+ rejectedOrders = rejected.([]*lendingstate.LendingItem)
+ }
+
+ txMatchTime := time.Unix(block.Header().Time.Int64(), 0).UTC()
+ statedb, _ := bc.State()
+
+ if err := lendingService.SyncDataToSDKNode(bc, statedb.Copy(), block, item, batch.TxHash, txMatchTime, trades, rejectedOrders, &dirtyOrderCount); err != nil {
+ log.Crit("lending: failed to SyncDataToSDKNode ", "blockNumber", block.Number(), "err", err)
+ }
+ }
+ }
+
+ // update finalizedTrades
+ if block.Number().Uint64()%bc.chainConfig.XDPoS.Epoch == common.LiquidateLendingTradeBlock {
+ finalizedTx, err := ExtractLendingFinalizedTradeTransactions(block.Transactions())
+ if err != nil {
+ log.Crit("failed to extract finalizedTrades transaction", "err", err)
+ }
+ finalizedTrades := map[common.Hash]*lendingstate.LendingTrade{}
+ finalizedData, ok := bc.finalizedTrade.Get(finalizedTx.TxHash)
+ if ok && finalizedData != nil {
+ finalizedTrades = finalizedData.(map[common.Hash]*lendingstate.LendingTrade)
+ }
+ if len(finalizedTrades) > 0 {
+ if err := lendingService.UpdateLiquidatedTrade(block.Time().Uint64(), finalizedTx, finalizedTrades); err != nil {
+ log.Crit("lending: failed to UpdateLiquidatedTrade ", "blockNumber", block.Number(), "err", err)
+ }
+ }
+ }
+}
+
+func (bc *BlockChain) AddMatchingResult(txHash common.Hash, matchingResults map[common.Hash]tradingstate.MatchingResult) {
+ for hash, result := range matchingResults {
+ cacheKey := crypto.Keccak256Hash(txHash.Bytes(), hash.Bytes())
+ bc.resultTrade.Add(cacheKey, result.Trades)
+ bc.rejectedOrders.Add(cacheKey, result.Rejects)
+ }
+}
+
+func (bc *BlockChain) AddLendingResult(txHash common.Hash, lendingResults map[common.Hash]lendingstate.MatchingResult) {
+ for hash, result := range lendingResults {
+ bc.resultLendingTrade.Add(crypto.Keccak256Hash(txHash.Bytes(), hash.Bytes()), result.Trades)
+ bc.rejectedLendingItem.Add(crypto.Keccak256Hash(txHash.Bytes(), hash.Bytes()), result.Rejects)
+ }
+}
+
+func (bc *BlockChain) AddFinalizedTrades(txHash common.Hash, trades map[common.Hash]*lendingstate.LendingTrade) {
+ bc.finalizedTrade.Add(txHash, trades)
+}
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 19fc05621e..e70ffe3ef8 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -18,20 +18,20 @@ package core
import (
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"math/rand"
"sync"
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// Test fork of length N starting from block i
@@ -117,7 +117,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
if err != nil {
return err
}
- receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{}, map[common.Address]*big.Int{})
+ receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, nil, vm.Config{}, map[common.Address]*big.Int{})
if err != nil {
blockchain.reportBlock(block, receipts, err)
return err
@@ -551,11 +551,11 @@ func testInsertNonceError(t *testing.T, full bool) {
func TestFastVsFullChains(t *testing.T) {
// Configure and generate a sample block chain
var (
- gendb, _ = ethdb.NewMemDatabase()
- key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- address = crypto.PubkeyToAddress(key.PublicKey)
- funds = big.NewInt(1000000000)
- gspec = &Genesis{
+ gendb = rawdb.NewMemoryDatabase()
+ key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ address = crypto.PubkeyToAddress(key.PublicKey)
+ funds = big.NewInt(1000000000)
+ gspec = &Genesis{
Config: params.TestChainConfig,
Alloc: GenesisAlloc{address: {Balance: funds}},
}
@@ -581,7 +581,7 @@ func TestFastVsFullChains(t *testing.T) {
}
})
// Import the chain as an archive node for the comparison baseline
- archiveDb, _ := ethdb.NewMemDatabase()
+ archiveDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(archiveDb)
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
defer archive.Stop()
@@ -590,7 +590,7 @@ func TestFastVsFullChains(t *testing.T) {
t.Fatalf("failed to process block %d: %v", n, err)
}
// Fast import the chain as a non-archive node to test
- fastDb, _ := ethdb.NewMemDatabase()
+ fastDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(fastDb)
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
defer fast.Stop()
@@ -639,12 +639,12 @@ func TestFastVsFullChains(t *testing.T) {
func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Configure and generate a sample block chain
var (
- gendb, _ = ethdb.NewMemDatabase()
- key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- address = crypto.PubkeyToAddress(key.PublicKey)
- funds = big.NewInt(1000000000)
- gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
- genesis = gspec.MustCommit(gendb)
+ gendb = rawdb.NewMemoryDatabase()
+ key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ address = crypto.PubkeyToAddress(key.PublicKey)
+ funds = big.NewInt(1000000000)
+ gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
+ genesis = gspec.MustCommit(gendb)
)
height := uint64(1024)
blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
@@ -667,7 +667,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
}
}
// Import the chain as an archive node and ensure all pointers are updated
- archiveDb, _ := ethdb.NewMemDatabase()
+ archiveDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(archiveDb)
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
@@ -681,7 +681,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
assert(t, "archive", archive, height/2, height/2, height/2)
// Import the chain as a non-archive node and ensure all pointers are updated
- fastDb, _ := ethdb.NewMemDatabase()
+ fastDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(fastDb)
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
defer fast.Stop()
@@ -701,7 +701,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
assert(t, "fast", fast, height/2, height/2, 0)
// Import the chain as a light node and ensure all pointers are updated
- lightDb, _ := ethdb.NewMemDatabase()
+ lightDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(lightDb)
light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
@@ -724,7 +724,7 @@ func TestChainTxReorgs(t *testing.T) {
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
gspec = &Genesis{
Config: params.TestChainConfig,
GasLimit: 3141592,
@@ -836,7 +836,7 @@ func TestLogReorgs(t *testing.T) {
var (
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
// this code generates a log
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
@@ -880,7 +880,7 @@ func TestLogReorgs(t *testing.T) {
//func TestReorgSideEvent(t *testing.T) {
// var (
-// db, _ = ethdb.NewMemDatabase()
+// db, _ = rawdb.NewMemoryDatabase()
// key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
// addr1 = crypto.PubkeyToAddress(key1.PublicKey)
// gspec = &Genesis{
@@ -1008,7 +1008,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
func TestEIP155Transition(t *testing.T) {
// Configure and generate a sample block chain
var (
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
address = crypto.PubkeyToAddress(key.PublicKey)
funds = big.NewInt(1000000000)
@@ -1112,7 +1112,7 @@ func TestEIP155Transition(t *testing.T) {
func TestEIP161AccountRemoval(t *testing.T) {
// Configure and generate a sample block chain
var (
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
address = crypto.PubkeyToAddress(key.PublicKey)
funds = big.NewInt(1000000000)
@@ -1179,12 +1179,12 @@ func TestEIP161AccountRemoval(t *testing.T) {
// tests that under weird reorg conditions the blockchain and its internal header-
// chain return the same latest block/header.
//
-// https://github.com/ethereum/go-ethereum/pull/15941how Source Control
+// https://github.com/XinFinOrg/XDPoSChain/pull/15941how Source Control
func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
// Generate a canonical chain to act as the main dataset
engine := ethash.NewFaker()
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
genesis := new(Genesis).MustCommit(db)
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
@@ -1200,7 +1200,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
}
// Import the canonical and fork chain side by side, verifying the current block
// and current header consistency
- diskdb, _ := ethdb.NewMemDatabase()
+ diskdb := rawdb.NewMemoryDatabase()
new(Genesis).MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
@@ -1229,7 +1229,7 @@ func TestTrieForkGC(t *testing.T) {
// Generate a canonical chain to act as the main dataset
engine := ethash.NewFaker()
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
genesis := new(Genesis).MustCommit(db)
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
@@ -1244,7 +1244,7 @@ func TestTrieForkGC(t *testing.T) {
forks[i] = fork[0]
}
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
- diskdb, _ := ethdb.NewMemDatabase()
+ diskdb := rawdb.NewMemoryDatabase()
new(Genesis).MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
@@ -1261,8 +1261,8 @@ func TestTrieForkGC(t *testing.T) {
}
// Dereference all the recent tries and ensure no past trie is left in
for i := 0; i < triesInMemory; i++ {
- chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root(), common.Hash{})
- chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root(), common.Hash{})
+ chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
+ chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
}
if len(chain.stateCache.TrieDB().Nodes()) > 0 {
t.Fatalf("stale tries still alive after garbase collection")
@@ -1275,7 +1275,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
// Generate the original common chain segment and the two competing forks
engine := ethash.NewFaker()
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
genesis := new(Genesis).MustCommit(db)
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
@@ -1283,7 +1283,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
// Import the shared chain and the original canonical one
- diskdb, _ := ethdb.NewMemDatabase()
+ diskdb := rawdb.NewMemoryDatabase()
new(Genesis).MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
diff --git a/core/blocks.go b/core/blocks.go
index f20ba4aaf2..1550ed350c 100644
--- a/core/blocks.go
+++ b/core/blocks.go
@@ -16,7 +16,7 @@
package core
-import "github.com/ethereum/go-ethereum/common"
+import "github.com/XinFinOrg/XDPoSChain/common"
// BadHashes represent a set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go
index 540085450d..2931c8fb97 100644
--- a/core/bloombits/generator.go
+++ b/core/bloombits/generator.go
@@ -19,7 +19,7 @@ package bloombits
import (
"errors"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// errSectionOutOfBounds is returned if the user tried to add more bloom filters
diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go
index f9bcef96e0..7e2242c140 100644
--- a/core/bloombits/generator_test.go
+++ b/core/bloombits/generator_test.go
@@ -21,7 +21,7 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// Tests that batched bloom bits are correctly rotated from the input bloom
diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go
index ce3031702f..2b219b33fb 100644
--- a/core/bloombits/matcher.go
+++ b/core/bloombits/matcher.go
@@ -26,8 +26,8 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/common/bitutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
// bloomIndexes represents the bit indexes inside the bloom filter that belong
diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go
index 7a5f78ef3a..45e5eec2da 100644
--- a/core/bloombits/matcher_test.go
+++ b/core/bloombits/matcher_test.go
@@ -23,7 +23,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
const testSectionSize = 4096
@@ -82,7 +82,7 @@ func TestMatcherRandom(t *testing.T) {
// Tests that the matcher can properly find matches if the starting block is
// shifter from a multiple of 8. This is needed to cover an optimisation with
-// bitset matching https://github.com/ethereum/go-ethereum/issues/15309.
+// bitset matching https://github.com/XinFinOrg/XDPoSChain/issues/15309.
func TestMatcherShifted(t *testing.T) {
// Block 0 always matches in the tests, skip ahead of first 8 blocks with the
// start to get a potential zero byte in the matcher bitset.
diff --git a/core/chain_indexer.go b/core/chain_indexer.go
index 158ed83245..7be107be85 100644
--- a/core/chain_indexer.go
+++ b/core/chain_indexer.go
@@ -23,11 +23,11 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// ChainIndexerBackend defines the methods needed to process chain segments in
diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go
index 9fc09eda51..c042a8319d 100644
--- a/core/chain_indexer_test.go
+++ b/core/chain_indexer_test.go
@@ -18,14 +18,14 @@ package core
import (
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"math/rand"
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// Runs multiple tests with randomized parameters.
@@ -47,7 +47,7 @@ func TestChainIndexerWithChildren(t *testing.T) {
// multiple backends. The section size and required confirmation count parameters
// are randomized.
func testChainIndexer(t *testing.T, count int) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
defer db.Close()
// Create a chain of indexers and ensure they all report empty
@@ -58,7 +58,7 @@ func testChainIndexer(t *testing.T, count int) {
confirmsReq = uint64(rand.Intn(10))
)
backends[i] = &testChainIndexBackend{t: t, processCh: make(chan uint64)}
- backends[i].indexer = NewChainIndexer(db, ethdb.NewTable(db, string([]byte{byte(i)})), backends[i], sectionSize, confirmsReq, 0, fmt.Sprintf("indexer-%d", i))
+ backends[i].indexer = NewChainIndexer(db, rawdb.NewTable(db, string([]byte{byte(i)})), backends[i], sectionSize, confirmsReq, 0, fmt.Sprintf("indexer-%d", i))
if sections, _, _ := backends[i].indexer.Sections(); sections != 0 {
t.Fatalf("Canonical section count mismatch: have %v, want %v", sections, 0)
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 68c9153f5d..a19cf0c5a5 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -20,14 +20,16 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/misc"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// So we can deterministically seed different blockchains
@@ -99,7 +101,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
}
feeCapacity := state.GetTRC21FeeCapacityFromState(b.statedb)
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
- receipt, gas, err, tokenFeeUsed := ApplyTransaction(b.config, feeCapacity, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
+ receipt, gas, err, tokenFeeUsed := ApplyTransaction(b.config, feeCapacity, bc, &b.header.Coinbase, b.gasPool, b.statedb, nil, b.header, tx, &b.header.GasUsed, vm.Config{})
if err != nil {
panic(err)
}
@@ -210,7 +212,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
}
if b.engine != nil {
- block, _ := b.engine.Finalize(b.chainReader, b.header, statedb, b.txs, b.uncles, b.receipts)
+ block, _ := b.engine.Finalize(b.chainReader, b.header, statedb, statedb.Copy(), b.txs, b.uncles, b.receipts)
// Write state changes to db
root, err := statedb.Commit(config.IsEIP158(b.header.Number))
if err != nil {
@@ -266,7 +268,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
// Initialize a fresh chain with only a genesis block
gspec := new(Genesis)
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
genesis := gspec.MustCommit(db)
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go
index fab82b9e3a..1dbcaf9fb0 100644
--- a/core/chain_makers_test.go
+++ b/core/chain_makers_test.go
@@ -18,14 +18,14 @@ package core
import (
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func ExampleGenerateChain() {
@@ -36,7 +36,7 @@ func ExampleGenerateChain() {
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
)
// Ensure that key1 has some funds in the genesis block.
gspec := &Genesis{
diff --git a/core/dao_test.go b/core/dao_test.go
index e0a3e3ff37..cfd636e7c0 100644
--- a/core/dao_test.go
+++ b/core/dao_test.go
@@ -17,13 +17,13 @@
package core
import (
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
@@ -32,13 +32,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
forkBlock := big.NewInt(32)
// Generate a common prefix for both pro-forkers and non-forkers
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
gspec := new(Genesis)
genesis := gspec.MustCommit(db)
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
// Create the concurrent, conflicting two nodes
- proDb, _ := ethdb.NewMemDatabase()
+ proDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(proDb)
proConf := *params.TestChainConfig
@@ -48,7 +48,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer proBc.Stop()
- conDb, _ := ethdb.NewMemDatabase()
+ conDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(conDb)
conConf := *params.TestChainConfig
@@ -67,7 +67,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
// Create a pro-fork block, and try to feed into the no-fork chain
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
@@ -92,7 +92,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
}
// Create a no-fork block, and try to feed into the pro-fork chain
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
@@ -118,7 +118,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
}
}
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
@@ -138,7 +138,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
}
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
diff --git a/core/database_util.go b/core/database_util.go
index 8c46989854..58a0865a6b 100644
--- a/core/database_util.go
+++ b/core/database_util.go
@@ -22,15 +22,16 @@ import (
"encoding/json"
"errors"
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/metrics"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
// DatabaseReader wraps the Get method of a backing data store.
@@ -353,7 +354,7 @@ func GetBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash)
}
// WriteCanonicalHash stores the canonical hash for the given block number.
-func WriteCanonicalHash(db ethdb.Putter, hash common.Hash, number uint64) error {
+func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) error {
key := append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...)
if err := db.Put(key, hash.Bytes()); err != nil {
log.Crit("Failed to store number to hash mapping", "err", err)
@@ -362,7 +363,7 @@ func WriteCanonicalHash(db ethdb.Putter, hash common.Hash, number uint64) error
}
// WriteHeadHeaderHash stores the head header's hash.
-func WriteHeadHeaderHash(db ethdb.Putter, hash common.Hash) error {
+func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) error {
if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
log.Crit("Failed to store last header's hash", "err", err)
}
@@ -370,7 +371,7 @@ func WriteHeadHeaderHash(db ethdb.Putter, hash common.Hash) error {
}
// WriteHeadBlockHash stores the head block's hash.
-func WriteHeadBlockHash(db ethdb.Putter, hash common.Hash) error {
+func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) error {
if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
log.Crit("Failed to store last block's hash", "err", err)
}
@@ -378,7 +379,7 @@ func WriteHeadBlockHash(db ethdb.Putter, hash common.Hash) error {
}
// WriteHeadFastBlockHash stores the fast head block's hash.
-func WriteHeadFastBlockHash(db ethdb.Putter, hash common.Hash) error {
+func WriteHeadFastBlockHash(db ethdb.KeyValueWriter, hash common.Hash) error {
if err := db.Put(headFastKey, hash.Bytes()); err != nil {
log.Crit("Failed to store last fast block's hash", "err", err)
}
@@ -387,7 +388,7 @@ func WriteHeadFastBlockHash(db ethdb.Putter, hash common.Hash) error {
// WriteTrieSyncProgress stores the fast sync trie process counter to support
// retrieving it across restarts.
-func WriteTrieSyncProgress(db ethdb.Putter, count uint64) error {
+func WriteTrieSyncProgress(db ethdb.KeyValueWriter, count uint64) error {
if err := db.Put(trieSyncKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
log.Crit("Failed to store fast sync trie progress", "err", err)
}
@@ -395,7 +396,7 @@ func WriteTrieSyncProgress(db ethdb.Putter, count uint64) error {
}
// WriteHeader serializes a block header into the database.
-func WriteHeader(db ethdb.Putter, header *types.Header) error {
+func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) error {
data, err := rlp.EncodeToBytes(header)
if err != nil {
return err
@@ -415,7 +416,7 @@ func WriteHeader(db ethdb.Putter, header *types.Header) error {
}
// WriteBody serializes the body of a block into the database.
-func WriteBody(db ethdb.Putter, hash common.Hash, number uint64, body *types.Body) error {
+func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) error {
data, err := rlp.EncodeToBytes(body)
if err != nil {
return err
@@ -424,7 +425,7 @@ func WriteBody(db ethdb.Putter, hash common.Hash, number uint64, body *types.Bod
}
// WriteBodyRLP writes a serialized body of a block into the database.
-func WriteBodyRLP(db ethdb.Putter, hash common.Hash, number uint64, rlp rlp.RawValue) error {
+func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) error {
key := append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
if err := db.Put(key, rlp); err != nil {
log.Crit("Failed to store block body", "err", err)
@@ -433,7 +434,7 @@ func WriteBodyRLP(db ethdb.Putter, hash common.Hash, number uint64, rlp rlp.RawV
}
// WriteTd serializes the total difficulty of a block into the database.
-func WriteTd(db ethdb.Putter, hash common.Hash, number uint64, td *big.Int) error {
+func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) error {
data, err := rlp.EncodeToBytes(td)
if err != nil {
return err
@@ -446,7 +447,7 @@ func WriteTd(db ethdb.Putter, hash common.Hash, number uint64, td *big.Int) erro
}
// WriteBlock serializes a block into the database, header and body separately.
-func WriteBlock(db ethdb.Putter, block *types.Block) error {
+func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) error {
// Store the body first to retain database consistency
if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
return err
@@ -461,7 +462,7 @@ func WriteBlock(db ethdb.Putter, block *types.Block) error {
// WriteBlockReceipts stores all the transaction receipts belonging to a block
// as a single receipt slice. This is used during chain reorganisations for
// rescheduling dropped transactions.
-func WriteBlockReceipts(db ethdb.Putter, hash common.Hash, number uint64, receipts types.Receipts) error {
+func WriteBlockReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) error {
// Convert the receipts into their storage form and serialize them
storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
for i, receipt := range receipts {
@@ -481,7 +482,7 @@ func WriteBlockReceipts(db ethdb.Putter, hash common.Hash, number uint64, receip
// WriteTxLookupEntries stores a positional metadata for every transaction from
// a block, enabling hash based transaction and receipt lookups.
-func WriteTxLookupEntries(db ethdb.Putter, block *types.Block) error {
+func WriteTxLookupEntries(db ethdb.KeyValueWriter, block *types.Block) error {
// Iterate over each transaction and encode its metadata
for i, tx := range block.Transactions() {
entry := TxLookupEntry{
@@ -502,7 +503,7 @@ func WriteTxLookupEntries(db ethdb.Putter, block *types.Block) error {
// WriteBloomBits writes the compressed bloom bits vector belonging to the given
// section and bit index.
-func WriteBloomBits(db ethdb.Putter, bit uint, section uint64, head common.Hash, bits []byte) {
+func WriteBloomBits(db ethdb.KeyValueWriter, bit uint, section uint64, head common.Hash, bits []byte) {
key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...)
binary.BigEndian.PutUint16(key[1:], uint16(bit))
@@ -554,7 +555,7 @@ func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) {
// PreimageTable returns a Database instance with the key prefix for preimage entries.
func PreimageTable(db ethdb.Database) ethdb.Database {
- return ethdb.NewTable(db, preimagePrefix)
+ return rawdb.NewTable(db, preimagePrefix)
}
// WritePreimages writes the provided set of preimages to the database. `number` is the
@@ -588,13 +589,13 @@ func GetBlockChainVersion(db DatabaseReader) int {
}
// WriteBlockChainVersion writes vsn as the version number to db.
-func WriteBlockChainVersion(db ethdb.Putter, vsn int) {
+func WriteBlockChainVersion(db ethdb.KeyValueWriter, vsn int) {
enc, _ := rlp.EncodeToBytes(uint(vsn))
db.Put([]byte("BlockchainVersion"), enc)
}
// WriteChainConfig writes the chain config settings to the database.
-func WriteChainConfig(db ethdb.Putter, hash common.Hash, cfg *params.ChainConfig) error {
+func WriteChainConfig(db ethdb.KeyValueWriter, hash common.Hash, cfg *params.ChainConfig) error {
// short circuit and ignore if nil config. GetChainConfig
// will return a default.
if cfg == nil {
diff --git a/core/database_util_test.go b/core/database_util_test.go
index ab4e45a478..a38a68fd41 100644
--- a/core/database_util_test.go
+++ b/core/database_util_test.go
@@ -18,19 +18,19 @@ package core
import (
"bytes"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
// Tests block header storage and retrieval operations.
func TestHeaderStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
// Create a test header to move around the database and make sure it's really new
header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")}
@@ -65,7 +65,7 @@ func TestHeaderStorage(t *testing.T) {
// Tests block body storage and retrieval operations.
func TestBodyStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
// Create a test body to move around the database and make sure it's really new
body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}}
@@ -105,7 +105,7 @@ func TestBodyStorage(t *testing.T) {
// Tests block storage and retrieval operations.
func TestBlockStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
// Create a test block to move around the database and make sure it's really new
block := types.NewBlockWithHeader(&types.Header{
@@ -157,7 +157,7 @@ func TestBlockStorage(t *testing.T) {
// Tests that partial block contents don't get reassembled into full blocks.
func TestPartialBlockStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
block := types.NewBlockWithHeader(&types.Header{
Extra: []byte("test block"),
UncleHash: types.EmptyUncleHash,
@@ -198,7 +198,7 @@ func TestPartialBlockStorage(t *testing.T) {
// Tests block total difficulty storage and retrieval operations.
func TestTdStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
// Create a test TD to move around the database and make sure it's really new
hash, td := common.Hash{}, big.NewInt(314)
@@ -223,7 +223,7 @@ func TestTdStorage(t *testing.T) {
// Tests that canonical numbers can be mapped to hashes and retrieved.
func TestCanonicalMappingStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
// Create a test canonical number and assinged hash to move around
hash, number := common.Hash{0: 0xff}, uint64(314)
@@ -248,7 +248,7 @@ func TestCanonicalMappingStorage(t *testing.T) {
// Tests that head headers and head blocks can be assigned, individually.
func TestHeadStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")})
blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")})
@@ -288,7 +288,7 @@ func TestHeadStorage(t *testing.T) {
// Tests that positional lookup metadata can be stored and retrieved.
func TestLookupStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
@@ -333,7 +333,7 @@ func TestLookupStorage(t *testing.T) {
// Tests that receipts associated with a single block can be stored and retrieved.
func TestBlockReceiptStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
receipt1 := &types.Receipt{
Status: types.ReceiptStatusFailed,
diff --git a/core/events.go b/core/events.go
index 6f404f612b..fbdbc030dd 100644
--- a/core/events.go
+++ b/core/events.go
@@ -17,13 +17,19 @@
package core
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// TxPreEvent is posted when a transaction enters the transaction pool.
type TxPreEvent struct{ Tx *types.Transaction }
+// OrderTxPreEvent is posted when a order transaction enters the order transaction pool.
+type OrderTxPreEvent struct{ Tx *types.OrderTransaction }
+
+// LendingTxPreEvent is posted when a order transaction enters the order transaction pool.
+type LendingTxPreEvent struct{ Tx *types.LendingTransaction }
+
// PendingLogsEvent is posted pre mining and notifies of pending logs.
type PendingLogsEvent struct {
Logs []*types.Log
diff --git a/core/evm.go b/core/evm.go
index 596ea95fb7..f3fb1a2349 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -19,24 +19,14 @@ package core
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
)
-// ChainContext supports retrieving headers and consensus parameters from the
-// current blockchain to be used during transaction processing.
-type ChainContext interface {
- // Engine retrieves the chain's consensus engine.
- Engine() consensus.Engine
-
- // GetHeader returns the hash corresponding to their hash.
- GetHeader(common.Hash, uint64) *types.Header
-}
-
// NewEVMContext creates a new context for use in the EVM.
-func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context {
+func NewEVMContext(msg Message, header *types.Header, chain consensus.ChainContext, author *common.Address) vm.Context {
// If we don't have an explicit author (i.e. not mining), extract from the header
var beneficiary common.Address
if author == nil {
@@ -59,25 +49,33 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
}
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
-func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
- var cache map[uint64]common.Hash
+func GetHashFn(ref *types.Header, chain consensus.ChainContext) func(n uint64) common.Hash {
+ // Cache will initially contain [refHash.parent],
+ // Then fill up with [refHash.p, refHash.pp, refHash.ppp, ...]
+ var cache []common.Hash
return func(n uint64) common.Hash {
// If there's no hash cache yet, make one
- if cache == nil {
- cache = map[uint64]common.Hash{
- ref.Number.Uint64() - 1: ref.ParentHash,
+ if len(cache) == 0 {
+ cache = append(cache, ref.ParentHash)
+ }
+ if idx := ref.Number.Uint64() - n - 1; idx < uint64(len(cache)) {
+ return cache[idx]
+ }
+ // No luck in the cache, but we can start iterating from the last element we already know
+ lastKnownHash := cache[len(cache)-1]
+ lastKnownNumber := ref.Number.Uint64() - uint64(len(cache))
+
+ for {
+ header := chain.GetHeader(lastKnownHash, lastKnownNumber)
+ if header == nil {
+ break
}
- }
- // Try to fulfill the request from the cache
- if hash, ok := cache[n]; ok {
- return hash
- }
- // Not cached, iterate the blocks and cache the hashes
- for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
- cache[header.Number.Uint64()-1] = header.ParentHash
- if n == header.Number.Uint64()-1 {
- return header.ParentHash
+ cache = append(cache, header.ParentHash)
+ lastKnownHash = header.ParentHash
+ lastKnownNumber = header.Number.Uint64() - 1
+ if n == lastKnownNumber {
+ return lastKnownHash
}
}
return common.Hash{}
diff --git a/core/gen_genesis.go b/core/gen_genesis.go
index bb8ea1d6a2..82fe48663c 100644
--- a/core/gen_genesis.go
+++ b/core/gen_genesis.go
@@ -7,10 +7,10 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
var _ = (*genesisSpecMarshaling)(nil)
diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go
index 64fb9b9248..9d3ea26d68 100644
--- a/core/gen_genesis_account.go
+++ b/core/gen_genesis_account.go
@@ -7,9 +7,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
var _ = (*genesisAccountMarshaling)(nil)
diff --git a/core/genesis.go b/core/genesis.go
index 655fcb6885..bec04f2c8e 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -25,15 +25,17 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
@@ -223,7 +225,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
// to the given database (or discards it if nil).
func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
if db == nil {
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
}
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
for addr, account := range g.Alloc {
diff --git a/core/genesis_test.go b/core/genesis_test.go
index e40acb5b1f..6b908123ae 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -17,16 +17,17 @@
package core
import (
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"reflect"
"testing"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/params"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
)
func TestDefaultGenesisBlock(t *testing.T) {
@@ -140,7 +141,7 @@ func TestSetupGenesis(t *testing.T) {
}
for _, test := range tests {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
config, hash, err := test.fn(db)
// Check the return values.
if !reflect.DeepEqual(err, test.wantErr) {
diff --git a/core/headerchain.go b/core/headerchain.go
index 2d1b0a2a18..cd61f76dbd 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -26,12 +26,12 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
"github.com/hashicorp/golang-lru"
)
diff --git a/core/helper_test.go b/core/helper_test.go
index 698a2924cb..c499d15db5 100644
--- a/core/helper_test.go
+++ b/core/helper_test.go
@@ -18,11 +18,12 @@ package core
import (
"container/list"
- "fmt"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/event"
)
// Implement our EthTest Manager
@@ -77,11 +78,7 @@ func (tm *TestManager) Db() ethdb.Database {
}
func NewTestManager() *TestManager {
- db, err := ethdb.NewMemDatabase()
- if err != nil {
- fmt.Println("Could not create mem-db, failing")
- return nil
- }
+ db := rawdb.NewMemoryDatabase()
testManager := &TestManager{}
testManager.eventMux = new(event.TypeMux)
diff --git a/core/lending_pool.go b/core/lending_pool.go
new file mode 100644
index 0000000000..4f600b2e58
--- /dev/null
+++ b/core/lending_pool.go
@@ -0,0 +1,1166 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
+
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "gopkg.in/karalabe/cookiejar.v2/collections/prque"
+)
+
+var (
+ ErrInvalidLendingSide = errors.New("invalid lending side")
+ ErrInvalidLendingType = errors.New("invalid lending type")
+ ErrInvalidLendingStatus = errors.New("invalid lending status")
+ ErrInvalidLendingUserAddress = errors.New("invalid lending user address")
+ ErrInvalidLendingQuantity = errors.New("invalid lending quantity")
+ ErrInvalidLendingInterest = errors.New("invalid lending interest")
+ ErrInvalidLendingRelayer = errors.New("invalid lending relayer address")
+ ErrInvalidLendingHash = errors.New("invalid lending hash")
+ ErrInvalidCancelledLending = errors.New("invalid cancel lending id")
+ ErrInvalidLendingTradeID = errors.New("invalid lending trade ID")
+ ErrInvalidLendingCollateral = errors.New("invalid collateral")
+)
+
+var (
+ LendingTypeLimit = "LO"
+ LendingTypeMarket = "MO"
+)
+
+// LendingPoolConfig are the configuration parameters of the order transaction pool.
+type LendingPoolConfig struct {
+ NoLocals bool // Whether local transaction handling should be disabled
+ Journal string // Journal of local transactions to survive node restarts
+ Rejournal time.Duration // Time interval to regenerate the local transaction journal
+
+ AccountSlots uint64 // Minimum number of executable transaction slots guaranteed per account
+ GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts
+ AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
+ GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts
+
+ Lifetime time.Duration // Maximum amount of time non-executable transaction are queued
+}
+
+// blockChain_XDCx add order state
+type blockChainLending interface {
+ CurrentBlock() *types.Block
+ GetBlock(hash common.Hash, number uint64) *types.Block
+ LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error)
+ StateAt(root common.Hash) (*state.StateDB, error)
+ SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
+ Engine() consensus.Engine
+ // GetHeader returns the hash corresponding to their hash.
+ GetHeader(common.Hash, uint64) *types.Header
+ // CurrentHeader retrieves the current header from the local chain.
+ CurrentHeader() *types.Header
+ // Config retrieves the blockchain's chain configuration.
+ Config() *params.ChainConfig
+}
+
+// DefaultLendingPoolConfig contains the default configurations for the transaction
+// pool.
+var DefaultLendingPoolConfig = LendingPoolConfig{
+ Journal: "",
+ Rejournal: time.Hour,
+
+ AccountSlots: 16,
+ GlobalSlots: 4096,
+ AccountQueue: 64,
+ GlobalQueue: 1024,
+
+ Lifetime: 3 * time.Hour,
+}
+
+// sanitize checks the provided user configurations and changes anything that's
+// unreasonable or unworkable.
+func (config *LendingPoolConfig) sanitize() LendingPoolConfig {
+ conf := *config
+ if conf.Rejournal < time.Second {
+ log.Warn("Sanitizing invalid LendingPool journal time", "provided", conf.Rejournal, "updated", time.Second)
+ conf.Rejournal = time.Second
+ }
+ return conf
+}
+
+// LendingPool contains all currently known transactions. Transactions
+// enter the pool when they are received from the network or submitted
+// locally. They exit the pool when they are included in the blockchain.
+//
+// The pool separates processable transactions (which can be applied to the
+// current state) and future transactions. Transactions move between those
+// two states over time as they are received and processed.
+type LendingPool struct {
+ config LendingPoolConfig
+ chainconfig *params.ChainConfig
+ chain blockChainLending
+
+ txFeed event.Feed
+ scope event.SubscriptionScope
+ chainHeadCh chan ChainHeadEvent
+ chainHeadSub event.Subscription
+ signer types.LendingSigner
+ mu sync.RWMutex
+
+ currentRootState *state.StateDB
+ currentLendingState *lendingstate.LendingStateDB // Current order state in the blockchain head
+ pendingState *lendingstate.LendingManagedState // Pending state tracking virtual nonces
+
+ locals *lendingAccountSet // Set of local transaction to exempt from eviction rules
+ journal *lendingtxJournal // Journal of local transaction to back up to disk
+
+ pending map[common.Address]*lendingtxList // All currently processable transactions
+ queue map[common.Address]*lendingtxList // Queued but non-processable transactions
+ beats map[common.Address]time.Time // Last heartbeat from each known account
+ all map[common.Hash]*types.LendingTransaction // All transactions to allow lookups
+ wg sync.WaitGroup // for shutdown sync
+ homestead bool
+ IsSigner func(address common.Address) bool
+}
+
+// NewLendingPool creates a new transaction pool to gather, sort and filter inbound
+// transactions from the network.
+func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *LendingPool {
+ // Sanitize the input to ensure no vulnerable gas prices are set
+ config := (&DefaultLendingPoolConfig).sanitize()
+ log.Debug("NewLendingPool start...", "current block", chain.CurrentBlock().Header().Number)
+ // Create the transaction pool with its initial settings
+ pool := &LendingPool{
+ config: config,
+ chainconfig: chainconfig,
+ chain: chain,
+ signer: types.LendingTxSigner{},
+ pending: make(map[common.Address]*lendingtxList),
+ queue: make(map[common.Address]*lendingtxList),
+ beats: make(map[common.Address]time.Time),
+ all: make(map[common.Hash]*types.LendingTransaction),
+ chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
+ }
+ pool.locals = newLendingAccountSet(pool.signer)
+ pool.reset(nil, chain.CurrentBlock())
+
+ // If local transactions and journaling is enabled, load from disk
+ if !config.NoLocals && config.Journal != "" {
+ pool.journal = newLendingTxJournal(config.Journal)
+
+ if err := pool.journal.load(pool.AddLocal); err != nil {
+ log.Warn("Failed to load transaction journal", "err", err)
+ }
+ if err := pool.journal.rotate(pool.local()); err != nil {
+ log.Warn("Failed to rotate transaction journal", "err", err)
+ }
+ }
+ // Subscribe events from blockchain
+ pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
+
+ // Start the event loop and return
+ pool.wg.Add(1)
+ go pool.loop()
+
+ return pool
+}
+
+// loop is the transaction pool's main event loop, waiting for and reacting to
+// outside blockchain events as well as for various reporting and transaction
+// eviction events.
+func (pool *LendingPool) loop() {
+ defer pool.wg.Done()
+
+ // Start the stats reporting and transaction eviction tickers
+ var prevPending, prevQueued int
+
+ report := time.NewTicker(statsReportInterval)
+ defer report.Stop()
+
+ evict := time.NewTicker(evictionInterval)
+ defer evict.Stop()
+
+ journal := time.NewTicker(pool.config.Rejournal)
+ defer journal.Stop()
+
+ // Track the previous head headers for transaction reorgs
+ head := pool.chain.CurrentBlock()
+
+ // Keep waiting for and reacting to the various events
+ for {
+ select {
+ // Handle ChainHeadEvent
+ case ev := <-pool.chainHeadCh:
+ if ev.Block != nil {
+ pool.mu.Lock()
+ if pool.chainconfig.IsHomestead(ev.Block.Number()) {
+ pool.homestead = true
+ }
+ log.Debug("LendingPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
+ pool.reset(head, ev.Block)
+ head = ev.Block
+
+ pool.mu.Unlock()
+ }
+ // Be unsubscribed due to system stopped
+ case <-pool.chainHeadSub.Err():
+ return
+
+ // Handle stats reporting ticks
+ case <-report.C:
+ pool.mu.RLock()
+ pending, queued := pool.stats()
+ pool.mu.RUnlock()
+ if pending != prevPending || queued != prevQueued {
+ log.Debug("Lending pool status report", "executable", pending, "queued", queued)
+ prevPending, prevQueued = pending, queued
+ }
+
+ // Handle inactive account transaction eviction
+ case <-evict.C:
+ pool.mu.Lock()
+ for addr := range pool.queue {
+ // Skip local transactions from the eviction mechanism
+ if pool.locals.contains(addr) {
+ continue
+ }
+ // Any non-locals old enough should be removed
+ if time.Since(pool.beats[addr]) > pool.config.Lifetime {
+ for _, tx := range pool.queue[addr].Flatten() {
+ pool.removeTx(tx.Hash())
+ }
+ }
+ }
+ pool.mu.Unlock()
+
+ // Handle local transaction journal rotation
+ case <-journal.C:
+ if pool.journal != nil {
+ pool.mu.Lock()
+ if err := pool.journal.rotate(pool.local()); err != nil {
+ log.Warn("Failed to rotate local tx journal", "err", err)
+ }
+ pool.mu.Unlock()
+ }
+ }
+ }
+}
+
+// reset retrieves the current state of the blockchain and ensures the content
+// of the transaction pool is valid with regard to the chain state.
+func (pool *LendingPool) reset(oldHead, newblock *types.Block) {
+ if !pool.chainconfig.IsTIPXDCX(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
+ return
+ }
+ // If we're reorging an old state, reinject all dropped transactions
+ var reinject types.LendingTransactions
+
+ // Initialize the internal state to the current head
+ if newblock == nil {
+ newblock = pool.chain.CurrentBlock()
+ }
+ newHead := newblock.Header()
+ lendingState, err := pool.chain.LendingStateAt(newblock)
+ if err != nil {
+ log.Error("Failed to reset LendingPool state", "err", err)
+ return
+ }
+ pool.currentLendingState = lendingState
+ pool.pendingState = lendingstate.ManageState(lendingState)
+
+ state, err := pool.chain.StateAt(newHead.Root)
+ if err != nil {
+ log.Error("Failed to reset pool state", "err", err)
+ return
+ }
+ pool.currentRootState = state
+
+ // Inject any transactions discarded due to reorgs
+ log.Debug("Reinjecting stale transactions", "count", len(reinject))
+ pool.addTxsLocked(reinject, false)
+
+ // validate the pool of pending transactions, this will remove
+ // any transactions that have been included in the block or
+ // have been invalidated because of another transaction (e.g.
+ // higher gas price)
+ pool.demoteUnexecutables()
+
+ // Update all accounts to the latest known pending nonce
+ for addr, list := range pool.pending {
+ txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
+ pool.pendingState.SetNonce(addr.Hash(), txs[len(txs)-1].Nonce()+1)
+ }
+ // Check the queue and move transactions over to the pending if possible
+ // or remove those that have become invalid
+ pool.promoteExecutables(nil)
+}
+
+// Stop terminates the transaction pool.
+func (pool *LendingPool) Stop() {
+ // Unsubscribe all subscriptions registered from LendingPool
+ pool.scope.Close()
+
+ // Unsubscribe subscriptions registered from blockchain
+ pool.chainHeadSub.Unsubscribe()
+ pool.wg.Wait()
+
+ if pool.journal != nil {
+ pool.journal.close()
+ }
+ log.Info("Transaction pool stopped")
+}
+
+// SubscribeTxPreEvent registers a subscription of TxPreEvent and
+// starts sending event to the given channel.
+func (pool *LendingPool) SubscribeTxPreEvent(ch chan<- LendingTxPreEvent) event.Subscription {
+ return pool.scope.Track(pool.txFeed.Subscribe(ch))
+}
+
+// State returns the virtual managed state of the transaction pool.
+func (pool *LendingPool) State() *lendingstate.LendingManagedState {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.pendingState
+}
+
+// Stats retrieves the current pool stats, namely the number of pending and the
+// number of queued (non-executable) transactions.
+func (pool *LendingPool) Stats() (int, int) {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.stats()
+}
+
+// stats retrieves the current pool stats, namely the number of pending and the
+// number of queued (non-executable) transactions.
+func (pool *LendingPool) stats() (int, int) {
+ pending := 0
+ for _, list := range pool.pending {
+ pending += list.Len()
+ }
+ queued := 0
+ for _, list := range pool.queue {
+ queued += list.Len()
+ }
+ return pending, queued
+}
+
+// Pending retrieves all currently processable transactions, groupped by origin
+// account and sorted by nonce. The returned transaction set is a copy and can be
+// freely modified by calling code.
+func (pool *LendingPool) Pending() (map[common.Address]types.LendingTransactions, error) {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ pending := make(map[common.Address]types.LendingTransactions)
+ for addr, list := range pool.pending {
+ pending[addr] = list.Flatten()
+ }
+ return pending, nil
+}
+
+// local retrieves all currently known local transactions, groupped by origin
+// account and sorted by nonce. The returned transaction set is a copy and can be
+// freely modified by calling code.
+func (pool *LendingPool) local() map[common.Address]types.LendingTransactions {
+ txs := make(map[common.Address]types.LendingTransactions)
+ for addr := range pool.locals.accounts {
+ if pending := pool.pending[addr]; pending != nil {
+ txs[addr] = append(txs[addr], pending.Flatten()...)
+ }
+ if queued := pool.queue[addr]; queued != nil {
+ txs[addr] = append(txs[addr], queued.Flatten()...)
+ }
+ }
+ return txs
+}
+
+// GetSender get sender from transaction
+func (pool *LendingPool) GetSender(tx *types.LendingTransaction) (common.Address, error) {
+ from, err := types.LendingSender(pool.signer, tx)
+ if err != nil {
+ return common.Address{}, ErrInvalidSender
+ }
+ return from, nil
+}
+
+func (pool *LendingPool) validateNewLending(cloneStateDb *state.StateDB, cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction) error {
+ lendingSide := tx.Side()
+ lendingType := tx.Type()
+ interest := tx.Interest()
+ quantity := tx.Quantity()
+ if quantity == nil || quantity.Sign() <= 0 {
+ return ErrInvalidLendingQuantity
+ }
+ if lendingType != LendingTypeMarket {
+ if interest <= 0 {
+ return ErrInvalidLendingInterest
+ }
+ }
+
+ if lendingSide != lendingstate.Investing && lendingSide != lendingstate.Borrowing {
+ return ErrInvalidLendingSide
+ }
+ if lendingType != LendingTypeLimit && lendingType != LendingTypeMarket {
+ return ErrInvalidLendingType
+ }
+ if tx.Side() == lendingstate.Borrowing {
+ if tx.CollateralToken().String() == lendingstate.EmptyAddress || tx.CollateralToken().String() == tx.LendingToken().String() {
+ return ErrInvalidLendingCollateral
+ }
+ validCollateral := false
+ collateralList, _ := lendingstate.GetCollaterals(cloneStateDb, tx.RelayerAddress(), tx.LendingToken(), tx.Term())
+ for _, collateral := range collateralList {
+ if tx.CollateralToken().String() == collateral.String() {
+ validCollateral = true
+ break
+ }
+ }
+ if !validCollateral {
+ return ErrInvalidLendingCollateral
+ }
+ }
+ if lendingType == LendingTypeLimit {
+ if err := pool.validateBalance(cloneStateDb, cloneLendingStateDb, tx, tx.CollateralToken()); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (pool *LendingPool) validateCancelledLending(cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction) error {
+ if tx.LendingId() == 0 {
+ return ErrInvalidCancelledLending
+ }
+ item := cloneLendingStateDb.GetLendingOrder(lendingstate.GetLendingOrderBookHash(tx.LendingToken(), tx.Term()), common.Uint64ToHash(tx.LendingId()))
+ if item == lendingstate.EmptyLendingOrder {
+ log.Debug("LendingOrder not found ", "LendingId", tx.LendingId(), "LendToken", tx.LendingToken().Hex(), "CollateralToken", tx.CollateralToken().Hex(), "Term", tx.Term())
+ return ErrInvalidCancelledLending
+ }
+ if item.Hash != tx.LendingHash() {
+ log.Debug("Invalid lending hash", "expected", item.Hash.Hex(), "got", tx.LendingHash().Hex())
+ return ErrInvalidLendingHash
+ }
+ return nil
+}
+func (pool *LendingPool) validateRepayLending(cloneStateDb *state.StateDB, cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction) error {
+ if tx.LendingTradeId() == 0 {
+ return ErrInvalidLendingTradeID
+ }
+ lendingBook := lendingstate.GetLendingOrderBookHash(tx.LendingToken(), tx.Term())
+ lendingTrade := cloneLendingStateDb.GetLendingTrade(lendingBook, common.Uint64ToHash(tx.LendingTradeId()))
+ if lendingTrade == lendingstate.EmptyLendingTrade {
+ return ErrInvalidLendingTradeID
+ }
+ if tx.UserAddress().String() != lendingTrade.Borrower.String() {
+ return ErrInvalidLendingUserAddress
+ }
+ if tx.RelayerAddress().String() != lendingTrade.BorrowingRelayer.String() {
+ return ErrInvalidLendingRelayer
+ }
+ if err := pool.validateBalance(cloneStateDb, cloneLendingStateDb, tx, tx.CollateralToken()); err != nil {
+ return err
+ }
+ return nil
+}
+func (pool *LendingPool) validateTopupLending(cloneStateDb *state.StateDB, cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction) error {
+ if tx.LendingTradeId() == 0 {
+ return ErrInvalidLendingTradeID
+ }
+ if tx.Quantity() == nil || tx.Quantity().Sign() <= 0 {
+ return ErrInvalidLendingQuantity
+ }
+ lendingBook := lendingstate.GetLendingOrderBookHash(tx.LendingToken(), tx.Term())
+ lendingTrade := cloneLendingStateDb.GetLendingTrade(lendingBook, common.Uint64ToHash(tx.LendingTradeId()))
+ if lendingTrade == lendingstate.EmptyLendingTrade {
+ return ErrInvalidLendingTradeID
+ }
+ if tx.UserAddress().String() != lendingTrade.Borrower.String() {
+ return ErrInvalidLendingUserAddress
+ }
+ if tx.RelayerAddress().String() != lendingTrade.BorrowingRelayer.String() {
+ return ErrInvalidLendingRelayer
+ }
+ if err := pool.validateBalance(cloneStateDb, cloneLendingStateDb, tx, lendingTrade.CollateralToken); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (pool *LendingPool) validateBalance(cloneStateDb *state.StateDB, cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction, collateralToken common.Address) error {
+ XDPoSEngine, ok := pool.chain.Engine().(*XDPoS.XDPoS)
+ if !ok {
+ return ErrNotXDPoS
+ }
+ XDCXServ := XDPoSEngine.GetXDCXService()
+ lendingServ := XDPoSEngine.GetLendingService()
+ if XDCXServ == nil {
+ return fmt.Errorf("XDCx not found in order validation")
+ }
+ lendingTokenDecimal, err := XDCXServ.GetTokenDecimal(pool.chain, cloneStateDb, tx.LendingToken())
+ if err != nil {
+ return fmt.Errorf("validateOrder: failed to get lendingTokenDecimal. err: %v", err)
+ }
+ author, err := pool.chain.Engine().Author(pool.chain.CurrentHeader())
+ if err != nil {
+ return err
+ }
+ tradingStateDb, err := XDCXServ.GetTradingState(pool.chain.CurrentBlock(), author)
+ if err != nil {
+ return fmt.Errorf("validateLending: failed to get tradingStateDb. Error: %v", err)
+ }
+ cloneTradingStateDb := tradingStateDb.Copy()
+ // collateralPrice: price of collateral by LendingToken
+ // Eg: LendingToken: USD, CollateralToken: BTC
+ // collateralPrice = BTC/USD (eg: 8000 USD)
+ // lendTokenXDCPrice: price of lendingToken in XDC quote
+ var lendTokenXDCPrice, collateralPrice, collateralTokenDecimal *big.Int
+ if collateralToken.String() != lendingstate.EmptyAddress {
+ collateralTokenDecimal, err = XDCXServ.GetTokenDecimal(pool.chain, cloneStateDb, collateralToken)
+ if err != nil {
+ return fmt.Errorf("validateOrder: failed to get collateralTokenDecimal. err: %v", err)
+ }
+ lendTokenXDCPrice, collateralPrice, err = lendingServ.GetCollateralPrices(pool.chain.CurrentHeader(), pool.chain, cloneStateDb, cloneTradingStateDb, collateralToken, tx.LendingToken())
+ if err != nil {
+ return err
+ }
+ if lendTokenXDCPrice == nil || lendTokenXDCPrice.Sign() <= 0 || collateralPrice == nil || collateralPrice.Sign() <= 0 {
+ log.Debug("ValidateLending: ErrInvalidCollateralPrice", "lendTokenXDCPrice", lendTokenXDCPrice, "collateralPrice", collateralPrice)
+ return lendingstate.ErrInvalidCollateralPrice
+ }
+ }
+ if lendTokenXDCPrice == nil || lendTokenXDCPrice.Sign() == 0 {
+ if tx.LendingToken().String() == common.XDCNativeAddress {
+ lendTokenXDCPrice = common.BasePrice
+ } else {
+ lendTokenXDCPrice, err = lendingServ.GetMediumTradePriceBeforeEpoch(pool.chain, cloneStateDb, cloneTradingStateDb, tx.LendingToken(), common.HexToAddress(common.XDCNativeAddress))
+ if err != nil {
+ return err
+ }
+ }
+ }
+ isXDCXLendingFork := pool.chain.Config().IsTIPXDCXLending(pool.chain.CurrentHeader().Number)
+ if err := lendingstate.VerifyBalance(isXDCXLendingFork,
+ cloneStateDb,
+ cloneLendingStateDb,
+ tx.Type(),
+ tx.Side(),
+ tx.Status(),
+ tx.UserAddress(),
+ tx.RelayerAddress(),
+ tx.LendingToken(),
+ tx.CollateralToken(),
+ tx.Quantity(),
+ lendingTokenDecimal,
+ collateralTokenDecimal,
+ lendTokenXDCPrice,
+ collateralPrice,
+ tx.Term(),
+ tx.LendingId(),
+ tx.LendingTradeId(),
+ ); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (pool *LendingPool) validateLending(tx *types.LendingTransaction) error {
+ cloneStateDb := pool.currentRootState.Copy()
+ cloneLendingStateDb := pool.currentLendingState.Copy()
+ from, _ := types.LendingSender(pool.signer, tx)
+ if from != tx.UserAddress() {
+ return ErrInvalidLendingUserAddress
+ }
+ if !lendingstate.IsValidRelayer(cloneStateDb, tx.RelayerAddress()) {
+ return fmt.Errorf("invalid lending relayer. ExchangeAddress: %s", tx.RelayerAddress().Hex())
+ }
+ if valid, _ := lendingstate.IsValidPair(cloneStateDb, tx.RelayerAddress(), tx.LendingToken(), tx.Term()); valid == false {
+ return fmt.Errorf("invalid pair. Relayer: %s. LendingToken: %s. Term: %d", tx.RelayerAddress().Hex(), tx.LendingToken().Hex(), tx.Term())
+ }
+ if tx.IsCreatedLending() {
+ return pool.validateNewLending(cloneStateDb, cloneLendingStateDb, tx)
+ }
+ if tx.IsCancelledLending() {
+ return pool.validateCancelledLending(cloneLendingStateDb, tx)
+ }
+ if tx.IsTopupLending() {
+ return pool.validateTopupLending(cloneStateDb, cloneLendingStateDb, tx)
+ }
+ if tx.IsRepayLending() {
+ return pool.validateRepayLending(cloneStateDb, cloneLendingStateDb, tx)
+ }
+
+ return ErrInvalidLendingStatus
+}
+
+// validateTx checks whether a transaction is valid according to the consensus
+// rules and adheres to some heuristic limits of the local node (price and size).
+func (pool *LendingPool) validateTx(tx *types.LendingTransaction, local bool) error {
+
+ // check if sender is in black list
+ if tx.From() != nil && common.Blacklist[*tx.From()] {
+ return fmt.Errorf("Reject transaction with sender in black-list: %v", tx.From().Hex())
+ }
+ // Heuristic limit, reject transactions over 32KB to prevent DOS attacks
+ if tx.Size() > 32*1024 {
+ return ErrOversizedData
+ }
+
+ // Make sure the transaction is signed properly
+ from, err := types.LendingSender(pool.signer, tx)
+ if err != nil {
+ return ErrInvalidSender
+ }
+ err = pool.validateLending(tx)
+ if err != nil {
+ return err
+ }
+ // Ensure the transaction adheres to nonce lending
+ if pool.currentLendingState.GetNonce(from.Hash()) > tx.Nonce() {
+ return ErrNonceTooLow
+ }
+ if pool.pendingState.GetNonce(from.Hash())+common.LimitThresholdNonceInQueue < tx.Nonce() {
+ return ErrNonceTooHigh
+ }
+
+ return nil
+}
+
+// add validates a transaction and inserts it into the non-executable queue for
+// later pending promotion and execution. If the transaction is a replacement for
+// an already pending or queued one, it overwrites the previous and returns this
+// so outer code doesn't uselessly call promote.
+//
+// If a newly added transaction is marked as local, its sending account will be
+// whitelisted, preventing any associated transaction from being dropped out of
+// the pool due to pricing constraints.
+func (pool *LendingPool) add(tx *types.LendingTransaction, local bool) (bool, error) {
+ // If the transaction is already known, discard it
+ hash := tx.Hash()
+ if pool.all[hash] != nil {
+ log.Debug("Discarding already known transaction", "hash", hash)
+ return false, fmt.Errorf("known transaction: %x", hash)
+ }
+
+ // If the transaction fails basic validation, discard it
+ if err := pool.validateTx(tx, local); err != nil {
+ log.Debug("Discarding invalid lending transaction", "hash", hash, "userAddress", tx.UserAddress, "status", tx.Status, "err", err)
+ invalidTxCounter.Inc(1)
+ return false, err
+ }
+ from, _ := types.LendingSender(pool.signer, tx) // already validated
+
+ // If the transaction pool is full, discard underpriced transactions
+ if uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
+ log.Debug("Add lending transaction to pool full", "hash", hash, "nonce", tx.Nonce())
+ return false, ErrPoolOverflow
+ }
+ // If the transaction is replacing an already pending one, do directly
+ if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
+ inserted, old := list.Add(tx)
+ if !inserted {
+ pendingDiscardCounter.Inc(1)
+ return false, ErrPendingNonceTooLow
+ }
+ if old != nil {
+ delete(pool.all, old.Hash())
+ pendingReplaceCounter.Inc(1)
+ }
+ pool.all[tx.Hash()] = tx
+ pool.journalTx(from, tx)
+
+ log.Debug("Lending Pooled new executable transaction", "hash", hash, "useraddress", tx.UserAddress(), "nonce", tx.Nonce(), "status", tx.Status(), "lendingid", tx.LendingId())
+ return old != nil, nil
+
+ }
+ // New transaction isn't replacing a pending one, push into queue
+ replace, err := pool.enqueueTx(hash, tx)
+ if err != nil {
+ return false, err
+ }
+ // Mark local addresses and journal local transactions
+ if local {
+ pool.locals.add(from)
+ }
+ pool.journalTx(from, tx)
+
+ log.Debug("Pooled new future transaction", "hash", hash, "from", from)
+ return replace, nil
+}
+
+// enqueueTx inserts a new transaction into the non-executable transaction queue.
+//
+// Note, this method assumes the pool lock is held!
+func (pool *LendingPool) enqueueTx(hash common.Hash, tx *types.LendingTransaction) (bool, error) {
+ // Try to insert the transaction into the future queue
+ from, _ := types.LendingSender(pool.signer, tx) // already validated
+ if pool.queue[from] == nil {
+ pool.queue[from] = newLendingTxList(false)
+ }
+ inserted, old := pool.queue[from].Add(tx)
+ if !inserted {
+ // An older transaction was better, discard this
+ queuedDiscardCounter.Inc(1)
+ return false, ErrPendingNonceTooLow
+ }
+ // Discard any previous transaction and mark this
+ if old != nil {
+ delete(pool.all, old.Hash())
+ queuedReplaceCounter.Inc(1)
+ }
+ pool.all[hash] = tx
+ return old != nil, nil
+}
+
+// journalTx adds the specified transaction to the local disk journal if it is
+// deemed to have been sent from a local account.
+func (pool *LendingPool) journalTx(from common.Address, tx *types.LendingTransaction) {
+ // Only journal if it's enabled and the transaction is local
+ if pool.journal == nil || !pool.locals.contains(from) {
+ return
+ }
+ if err := pool.journal.insert(tx); err != nil {
+ log.Warn("Failed to journal local transaction", "err", err)
+ }
+}
+
+// promoteTx adds a transaction to the pending (processable) list of transactions.
+//
+// Note, this method assumes the pool lock is held!
+func (pool *LendingPool) promoteTx(addr common.Address, hash common.Hash, tx *types.LendingTransaction) {
+ // Try to insert the transaction into the pending queue
+ if pool.pending[addr] == nil {
+ pool.pending[addr] = newLendingTxList(true)
+ }
+ list := pool.pending[addr]
+
+ inserted, old := list.Add(tx)
+ if !inserted {
+ // An older transaction was better, discard this
+ delete(pool.all, hash)
+ pendingDiscardCounter.Inc(1)
+ return
+ }
+ // Otherwise discard any previous transaction and mark this
+ if old != nil {
+ delete(pool.all, old.Hash())
+ pendingReplaceCounter.Inc(1)
+ }
+ // Failsafe to work around direct pending inserts (tests)
+ if pool.all[hash] == nil {
+ pool.all[hash] = tx
+ }
+ // Set the potentially new pending nonce and notify any subsystems of the new tx
+ pool.beats[addr] = time.Now()
+ pool.pendingState.SetNonce(addr.Hash(), tx.Nonce()+1)
+
+ go pool.txFeed.Send(LendingTxPreEvent{tx})
+}
+
+// AddLocal enqueues a single transaction into the pool if it is valid, marking
+// the sender as a local one in the mean time, ensuring it goes around the local
+// pricing constraints.
+func (pool *LendingPool) AddLocal(tx *types.LendingTransaction) error {
+ log.Debug("Lending add local tx", "relayeraddress", tx.RelayerAddress().Hex(), "addr", tx.UserAddress(), "nonce", tx.Nonce(), "ohash", tx.LendingHash().Hex(), "status", tx.Status(), "lendingid", tx.LendingId(), "lendingtradeid", tx.LendingTradeId())
+ return pool.addTx(tx, !pool.config.NoLocals)
+}
+
+// AddRemote enqueues a single transaction into the pool if it is valid. If the
+// sender is not among the locally tracked ones, full pricing constraints will
+// apply.
+func (pool *LendingPool) AddRemote(tx *types.LendingTransaction) error {
+ return pool.addTx(tx, false)
+}
+
+// AddLocals enqueues a batch of transactions into the pool if they are valid,
+// marking the senders as a local ones in the mean time, ensuring they go around
+// the local pricing constraints.
+func (pool *LendingPool) AddLocals(txs []*types.LendingTransaction) []error {
+ return pool.addTxs(txs, !pool.config.NoLocals)
+}
+
+// AddRemotes enqueues a batch of transactions into the pool if they are valid.
+// If the senders are not among the locally tracked ones, full pricing constraints
+// will apply.
+func (pool *LendingPool) AddRemotes(txs []*types.LendingTransaction) []error {
+ return pool.addTxs(txs, false)
+}
+
+// addTx enqueues a single transaction into the pool if it is valid.
+func (pool *LendingPool) addTx(tx *types.LendingTransaction, local bool) error {
+ if !pool.chainconfig.IsTIPXDCX(pool.chain.CurrentBlock().Number()) {
+ return nil
+ }
+ tx.CacheHash()
+ types.CacheLendingSigner(pool.signer, tx)
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ // Try to inject the transaction and update any state
+ replace, err := pool.add(tx, local)
+ if err != nil {
+ return err
+ }
+ // If we added a new transaction, run promotion checks and return
+ if !replace {
+ from, _ := types.LendingSender(pool.signer, tx) // already validated
+ pool.promoteExecutables([]common.Address{from})
+ }
+ return nil
+}
+
+// addTxs attempts to queue a batch of transactions if they are valid.
+func (pool *LendingPool) addTxs(txs []*types.LendingTransaction, local bool) []error {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ return pool.addTxsLocked(txs, local)
+}
+
+// addTxsLocked attempts to queue a batch of transactions if they are valid,
+// whilst assuming the transaction pool lock is already held.
+func (pool *LendingPool) addTxsLocked(txs []*types.LendingTransaction, local bool) []error {
+ // Add the batch of transaction, tracking the accepted ones
+ dirty := make(map[common.Address]struct{})
+ errs := make([]error, len(txs))
+
+ for i, tx := range txs {
+ var replace bool
+ if replace, errs[i] = pool.add(tx, local); errs[i] == nil {
+ if !replace {
+ from, _ := types.LendingSender(pool.signer, tx) // already validated
+ dirty[from] = struct{}{}
+ }
+ }
+ }
+ // Only reprocess the internal state if something was actually added
+ if len(dirty) > 0 {
+ addrs := make([]common.Address, 0, len(dirty))
+ for addr := range dirty {
+ addrs = append(addrs, addr)
+ }
+ pool.promoteExecutables(addrs)
+ }
+ return errs
+}
+
+// Status returns the status (unknown/pending/queued) of a batch of transactions
+// identified by their hashes.
+func (pool *LendingPool) Status(hashes []common.Hash) []TxStatus {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ status := make([]TxStatus, len(hashes))
+ for i, hash := range hashes {
+ if tx := pool.all[hash]; tx != nil {
+ from, _ := types.LendingSender(pool.signer, tx) // already validated
+ if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil {
+ status[i] = TxStatusPending
+ } else {
+ status[i] = TxStatusQueued
+ }
+ }
+ }
+ return status
+}
+
+// Get returns a transaction if it is contained in the pool
+// and nil otherwise.
+func (pool *LendingPool) Get(hash common.Hash) *types.LendingTransaction {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.all[hash]
+}
+
+// removeTx removes a single transaction from the queue, moving all subsequent
+// transactions back to the future queue.
+func (pool *LendingPool) removeTx(hash common.Hash) {
+ // Fetch the transaction we wish to delete
+ tx, ok := pool.all[hash]
+ if !ok {
+ return
+ }
+ addr, _ := types.LendingSender(pool.signer, tx) // already validated during insertion
+
+ // Remove it from the list of known transactions
+ delete(pool.all, hash)
+
+ // Remove the transaction from the pending lists and reset the account nonce
+ if pending := pool.pending[addr]; pending != nil {
+ if removed, invalids := pending.Remove(tx); removed {
+ // If no more pending transactions are left, remove the list
+ if pending.Empty() {
+ delete(pool.pending, addr)
+ delete(pool.beats, addr)
+ }
+ // Postpone any invalidated transactions
+ for _, tx := range invalids {
+ pool.enqueueTx(tx.Hash(), tx)
+ }
+ // Update the account nonce if needed
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr.Hash()) > nonce {
+ pool.pendingState.SetNonce(addr.Hash(), nonce)
+ }
+ return
+ }
+ }
+ // Transaction is in the future queue
+ if future := pool.queue[addr]; future != nil {
+ future.Remove(tx)
+ if future.Empty() {
+ delete(pool.queue, addr)
+ }
+ }
+}
+
+// promoteExecutables moves transactions that have become processable from the
+// future queue to the set of pending transactions. During this process, all
+// invalidated transactions (low nonce, low balance) are deleted.
+func (pool *LendingPool) promoteExecutables(accounts []common.Address) {
+ start := time.Now()
+ log.Debug("start promoteExecutables")
+ defer log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start)))
+ // Gather all the accounts potentially needing updates
+ if accounts == nil {
+ accounts = make([]common.Address, 0, len(pool.queue))
+ for addr := range pool.queue {
+ accounts = append(accounts, addr)
+ }
+ }
+ // Iterate over all accounts and promote any executable transactions
+ for _, addr := range accounts {
+ list := pool.queue[addr]
+ if list == nil {
+ continue // Just in case someone calls with a non existing account
+ }
+ // Drop all transactions that are deemed too old (low nonce)
+ for _, tx := range list.Forward(pool.currentLendingState.GetNonce(addr.Hash())) {
+ hash := tx.Hash()
+ log.Trace("Removed old queued transaction", "hash", hash)
+ delete(pool.all, hash)
+
+ }
+
+ // Gather all executable transactions and promote them
+ for _, tx := range list.Ready(pool.pendingState.GetNonce(addr.Hash())) {
+ hash := tx.Hash()
+ log.Trace("Promoting queued transaction", "hash", hash)
+ pool.promoteTx(addr, hash, tx)
+ }
+ // Drop all transactions over the allowed limit
+ if !pool.locals.contains(addr) {
+ for _, tx := range list.Cap(int(pool.config.AccountQueue)) {
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ queuedRateLimitCounter.Inc(1)
+ log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
+ }
+ }
+ // Delete the entire queue entry if it became empty.
+ if list.Empty() {
+ delete(pool.queue, addr)
+ }
+ }
+ // If the pending limit is overflown, start equalizing allowances
+ pending := uint64(0)
+ for _, list := range pool.pending {
+ pending += uint64(list.Len())
+ }
+ if pending > pool.config.GlobalSlots {
+ pendingBeforeCap := pending
+ // Assemble a spam order to penalize large transactors first
+ spammers := prque.New()
+ for addr, list := range pool.pending {
+ // Only evict transactions from high rollers
+ if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots {
+ spammers.Push(addr, float32(list.Len()))
+ }
+ }
+ // Gradually drop transactions from offenders
+ offenders := []common.Address{}
+ for pending > pool.config.GlobalSlots && !spammers.Empty() {
+ // Retrieve the next offender if not local address
+ offender, _ := spammers.Pop()
+ offenders = append(offenders, offender.(common.Address))
+
+ // Equalize balances until all the same or below threshold
+ if len(offenders) > 1 {
+ // Calculate the equalization threshold for all current offenders
+ threshold := pool.pending[offender.(common.Address)].Len()
+
+ // Iteratively reduce all offenders until below limit or threshold reached
+ for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold {
+ for i := 0; i < len(offenders)-1; i++ {
+ list := pool.pending[offenders[i]]
+ for _, tx := range list.Cap(list.Len() - 1) {
+ // Drop the transaction from the global pools too
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ // Update the account nonce to the dropped transaction
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i].Hash()) > nonce {
+ pool.pendingState.SetNonce(offenders[i].Hash(), nonce)
+ }
+ log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
+ }
+ pending--
+ }
+ }
+ }
+ }
+ // If still above threshold, reduce to limit or min allowance
+ if pending > pool.config.GlobalSlots && len(offenders) > 0 {
+ for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots {
+ for _, addr := range offenders {
+ list := pool.pending[addr]
+ for _, tx := range list.Cap(list.Len() - 1) {
+ // Drop the transaction from the global pools too
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ // Update the account nonce to the dropped transaction
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr.Hash()) > nonce {
+ pool.pendingState.SetNonce(addr.Hash(), nonce)
+ }
+ log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
+ }
+ pending--
+ }
+ }
+ }
+ pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
+ }
+ // If we've queued more transactions than the hard limit, drop oldest ones
+ queued := uint64(0)
+ for _, list := range pool.queue {
+ queued += uint64(list.Len())
+ }
+ if queued > pool.config.GlobalQueue {
+ // Sort all accounts with queued transactions by heartbeat
+ addresses := make(addresssByHeartbeat, 0, len(pool.queue))
+ for addr := range pool.queue {
+ if !pool.locals.contains(addr) { // don't drop locals
+ addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
+ }
+ }
+ sort.Sort(addresses)
+
+ // Drop transactions until the total is below the limit or only locals remain
+ for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; {
+ addr := addresses[len(addresses)-1]
+ list := pool.queue[addr.address]
+
+ addresses = addresses[:len(addresses)-1]
+
+ // Drop all transactions if they are less than the overflow
+ if size := uint64(list.Len()); size <= drop {
+ for _, tx := range list.Flatten() {
+ pool.removeTx(tx.Hash())
+ }
+ drop -= size
+ queuedRateLimitCounter.Inc(int64(size))
+ continue
+ }
+ // Otherwise drop only last few transactions
+ txs := list.Flatten()
+ for i := len(txs) - 1; i >= 0 && drop > 0; i-- {
+ pool.removeTx(txs[i].Hash())
+ drop--
+ queuedRateLimitCounter.Inc(1)
+ }
+ }
+ }
+}
+
+// demoteUnexecutables removes invalid and processed transactions from the pools
+// executable/pending queue and any subsequent transactions that become unexecutable
+// are moved back into the future queue.
+func (pool *LendingPool) demoteUnexecutables() {
+ // Iterate over all accounts and demote any non-executable transactions
+ for addr, list := range pool.pending {
+ nonce := pool.currentLendingState.GetNonce(addr.Hash())
+ log.Debug("demoteUnexecutables", "addr", addr.Hex(), "nonce", nonce)
+ // Drop all transactions that are deemed too old (low nonce)
+ for _, tx := range list.Forward(nonce) {
+ hash := tx.Hash()
+ log.Debug("Removed old pending transaction", "hash", hash)
+ delete(pool.all, hash)
+ }
+
+ // If there's a gap in front, warn (should never happen) and postpone all transactions
+ if list.Len() > 0 && list.txs.Get(nonce) == nil {
+ for _, tx := range list.Cap(0) {
+ hash := tx.Hash()
+ log.Warn("Demoting invalidated transaction", "hash", hash)
+ pool.enqueueTx(hash, tx)
+ }
+ }
+ // Delete the entire queue entry if it became empty.
+ if list.Empty() {
+ delete(pool.pending, addr)
+ delete(pool.beats, addr)
+ }
+ }
+}
+
+type lendingAccountSet struct {
+ accounts map[common.Address]struct{}
+ signer types.LendingSigner
+}
+
+// newAccountSet creates a new address set with an associated signer for sender
+// derivations.
+func newLendingAccountSet(signer types.LendingSigner) *lendingAccountSet {
+ return &lendingAccountSet{
+ accounts: make(map[common.Address]struct{}),
+ signer: signer,
+ }
+}
+
+// contains checks if a given address is contained within the set.
+func (as *lendingAccountSet) contains(addr common.Address) bool {
+ _, exist := as.accounts[addr]
+ return exist
+}
+
+// containsTx checks if the sender of a given tx is within the set. If the sender
+// cannot be derived, this method returns false.
+func (as *lendingAccountSet) containsTx(tx *types.LendingTransaction) bool {
+ if addr, err := types.LendingSender(as.signer, tx); err == nil {
+ return as.contains(addr)
+ }
+ return false
+}
+
+// add inserts a new address into the set to track.
+func (as *lendingAccountSet) add(addr common.Address) {
+ as.accounts[addr] = struct{}{}
+}
diff --git a/core/lending_pool_test.go b/core/lending_pool_test.go
new file mode 100644
index 0000000000..2d8104403f
--- /dev/null
+++ b/core/lending_pool_test.go
@@ -0,0 +1,287 @@
+package core
+
+import (
+ "context"
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
+ "log"
+ "math/big"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+)
+
+type LendingMsg struct {
+ AccountNonce uint64 `json:"nonce" gencodec:"required"`
+ Quantity *big.Int `json:"quantity,omitempty"`
+ RelayerAddress common.Address `json:"relayerAddress,omitempty"`
+ UserAddress common.Address `json:"userAddress,omitempty"`
+ CollateralToken common.Address `json:"collateralToken,omitempty"`
+ AutoTopUp bool `json:"autoTopUp,omitempty"`
+ LendingToken common.Address `json:"lendingToken,omitempty"`
+ Term uint64 `json:"term,omitempty"`
+ Interest uint64 `json:"interest,omitempty"`
+ Status string `json:"status,omitempty"`
+ Side string `json:"side,omitempty"`
+ Type string `json:"type,omitempty"`
+ LendingId uint64 `json:"lendingId,omitempty"`
+ LendingTradeId uint64 `json:"tradeId,omitempty"`
+ ExtraData string `json:"extraData,omitempty"`
+ // Signature values
+ V *big.Int `json:"v" gencodec:"required"`
+ R *big.Int `json:"r" gencodec:"required"`
+ S *big.Int `json:"s" gencodec:"required"`
+
+ // This is only used when marshaling to JSON.
+ Hash common.Hash `json:"hash" rlp:"-"`
+}
+
+func getLendingNonce(userAddress common.Address) (uint64, error) {
+ rpcClient, err := rpc.DialHTTP("http://127.0.0.1:8501")
+ defer rpcClient.Close()
+ if err != nil {
+ return 0, err
+ }
+ var result interface{}
+ err = rpcClient.Call(&result, "XDCx_getLendingOrderCount", userAddress)
+ if err != nil {
+ return 0, err
+ }
+ s := result.(string)
+ s = strings.TrimPrefix(s, "0x")
+ n, err := strconv.ParseUint(s, 16, 32)
+ return uint64(n), nil
+}
+
+func (l *LendingMsg) computeHash() common.Hash {
+ borrowing := l.Side == lendingstate.Borrowing
+ sha := sha3.NewKeccak256()
+ if l.Type == lendingstate.Repay {
+ sha.Write(common.BigToHash(big.NewInt(int64(l.AccountNonce))).Bytes())
+ sha.Write([]byte(l.Status))
+ sha.Write(l.RelayerAddress.Bytes())
+ sha.Write(l.UserAddress.Bytes())
+ sha.Write(l.LendingToken.Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.Term))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.LendingTradeId))).Bytes())
+ } else if l.Type == lendingstate.TopUp {
+ sha.Write(common.BigToHash(big.NewInt(int64(l.AccountNonce))).Bytes())
+ sha.Write([]byte(l.Status))
+ sha.Write(l.RelayerAddress.Bytes())
+ sha.Write(l.UserAddress.Bytes())
+ sha.Write(l.LendingToken.Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.Term))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.LendingTradeId))).Bytes())
+ sha.Write(common.BigToHash(l.Quantity).Bytes())
+ } else {
+ if l.Status == lendingstate.LendingStatusCancelled {
+ sha := sha3.NewKeccak256()
+ sha.Write(l.Hash.Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.AccountNonce))).Bytes())
+ sha.Write(l.UserAddress.Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.LendingId))).Bytes())
+ sha.Write([]byte(l.Status))
+ sha.Write(l.RelayerAddress.Bytes())
+ } else if l.Status == lendingstate.LendingStatusNew {
+ sha.Write(l.RelayerAddress.Bytes())
+ sha.Write(l.UserAddress.Bytes())
+ if borrowing {
+ sha.Write(l.CollateralToken.Bytes())
+ }
+ sha.Write(l.LendingToken.Bytes())
+ sha.Write(common.BigToHash(l.Quantity).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.Term))).Bytes())
+ if l.Type == lendingstate.Limit {
+ sha.Write(common.BigToHash(big.NewInt(int64(l.Interest))).Bytes())
+ }
+ sha.Write([]byte(l.Side))
+ sha.Write([]byte(l.Status))
+ sha.Write([]byte(l.Type))
+ sha.Write(common.BigToHash(big.NewInt(int64(l.AccountNonce))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(l.LendingTradeId))).Bytes())
+ if borrowing {
+ autoTopUp := int64(0)
+ if l.AutoTopUp {
+ autoTopUp = int64(1)
+ }
+ sha.Write(common.BigToHash(big.NewInt(autoTopUp)).Bytes())
+ }
+ }
+ }
+
+ return common.BytesToHash(sha.Sum(nil))
+
+}
+func testSendLending(key string, nonce uint64, lendToken, collateralToken common.Address, amount *big.Int, interest uint64, side string, status string, autoTopUp bool, lendingId, tradeId uint64, cancelledHash common.Hash, extraData string) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+ privateKey, err := crypto.HexToECDSA(key)
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &LendingMsg{
+ AccountNonce: nonce,
+ Quantity: amount,
+ RelayerAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ LendingToken: lendToken,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ Term: 86400,
+ AutoTopUp: autoTopUp,
+ Interest: interest,
+ LendingId: lendingId,
+ LendingTradeId: tradeId,
+ ExtraData: extraData,
+ }
+ if msg.Side == lendingstate.Borrowing {
+ msg.CollateralToken = collateralToken
+ }
+ if cancelledHash != (common.Hash{}) {
+ msg.Hash = cancelledHash
+ } else {
+ msg.Hash = msg.computeHash()
+ }
+
+ tx := types.NewLendingTransaction(msg.AccountNonce, msg.Quantity, msg.Interest, msg.Term, msg.RelayerAddress, msg.UserAddress, msg.LendingToken, msg.CollateralToken, msg.AutoTopUp, msg.Status, msg.Side, msg.Type, msg.Hash, lendingId, tradeId, msg.ExtraData)
+ signedTx, err := types.LendingSignTx(tx, types.LendingTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+ fmt.Println("nonce", nonce, "side", msg.Side, "quantity", new(big.Int).Div(msg.Quantity, _1E8), "Interest", new(big.Int).Div(new(big.Int).SetUint64(msg.Interest), _1E8), "%")
+
+ err = client.SendLendingTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func TestSendLending(t *testing.T) {
+ t.SkipNow() //TODO: remove it to run this test
+ key := ""
+ privateKey, err := crypto.HexToECDSA(key)
+ if err != nil {
+ log.Print(err)
+ }
+ nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey))
+ if err != nil {
+ t.Error("fail to get nonce")
+ t.FailNow()
+ }
+
+ for true {
+ // 10%
+ interestRate := 10 * common.BaseLendingInterest.Uint64()
+ // lendToken: USD, collateral: BTC
+ // amount 1000 USD
+ testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, USDAddress, BTCAddress, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+
+ // lendToken: USD, collateral: XDC
+ // amount 1000 USD
+ testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, USDAddress, common.HexToAddress(common.XDCNativeAddress), new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+
+ // lendToken: BTC, collateral: XDC
+ // amount 1 BTC
+ testSendLending(key, nonce, BTCAddress, common.Address{}, new(big.Int).Mul(_1E18, big.NewInt(1)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, BTCAddress, common.HexToAddress(common.XDCNativeAddress), new(big.Int).Mul(_1E18, big.NewInt(1)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+
+ // lendToken: BTC, collateral: ETH
+ // amount 1 BTC
+ testSendLending(key, nonce, BTCAddress, common.Address{}, new(big.Int).Mul(_1E18, big.NewInt(1)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, BTCAddress, ETHAddress, new(big.Int).Mul(_1E18, big.NewInt(1)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+
+ // lendToken: XDC, collateral: BTC
+ // amount 1000 XDC
+ testSendLending(key, nonce, common.HexToAddress(common.XDCNativeAddress), common.Address{}, new(big.Int).Mul(_1E18, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, common.HexToAddress(common.XDCNativeAddress), BTCAddress, new(big.Int).Mul(_1E18, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+
+ // lendToken: XDC, collateral: ETH
+ // amount 1000 XDC
+ testSendLending(key, nonce, common.HexToAddress(common.XDCNativeAddress), common.Address{}, new(big.Int).Mul(_1E18, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ testSendLending(key, nonce, common.HexToAddress(common.XDCNativeAddress), ETHAddress, new(big.Int).Mul(_1E18, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(time.Second)
+ }
+}
+
+func TestCancelLending(t *testing.T) {
+ t.SkipNow() //TODO: remove it to run this test
+ key := ""
+ privateKey, err := crypto.HexToECDSA(key)
+ if err != nil {
+ log.Print(err)
+ }
+ nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey))
+ if err != nil {
+ t.Error("fail to get nonce")
+ t.FailNow()
+ }
+
+ // 10%
+ interestRate := 10 * common.BaseLendingInterest.Uint64()
+ testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ nonce++
+ time.Sleep(2 * time.Second)
+ //TODO: run the above testcase first, then updating lendingId, Hash
+ testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusCancelled, true, 1, 0, common.HexToHash("0x3da4e24b9c0f60e04cdb4c4494de37203c6e1a354907cbd6d9bbbe2e52aecaab"), "")
+
+}
+
+func TestRecallLending(t *testing.T) {
+ t.SkipNow() //TODO: remove it to run this test
+ key := ""
+ privateKey, err := crypto.HexToECDSA(key)
+ if err != nil {
+ log.Print(err)
+ }
+ nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey))
+ if err != nil {
+ t.Error("fail to get nonce")
+ t.FailNow()
+ }
+ interestRate := 10 * common.BaseLendingInterest.Uint64()
+ testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ time.Sleep(2 * time.Second)
+ nonce, err = getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey))
+ if err != nil {
+ t.Error("fail to get nonce")
+ t.FailNow()
+ }
+ testSendLending(key, nonce, USDAddress, common.HexToAddress(common.XDCNativeAddress), new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "")
+ time.Sleep(2 * time.Second)
+}
diff --git a/core/lending_tx_journal.go b/core/lending_tx_journal.go
new file mode 100644
index 0000000000..4bf835e9ce
--- /dev/null
+++ b/core/lending_tx_journal.go
@@ -0,0 +1,149 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "io"
+ "os"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+)
+
+// lendingtxJournal is a rotating log of transactions with the aim of storing locally
+// created transactions to allow non-executed ones to survive node restarts.
+type lendingtxJournal struct {
+ path string // Filesystem path to store the transactions at
+ writer io.WriteCloser // Output stream to write new transactions into
+}
+
+// newLendingTxJournal creates a new transaction journal to
+func newLendingTxJournal(path string) *lendingtxJournal {
+ return &lendingtxJournal{
+ path: path,
+ }
+}
+
+// load parses a transaction journal dump from disk, loading its contents into
+// the specified pool.
+func (journal *lendingtxJournal) load(add func(*types.LendingTransaction) error) error {
+ // Skip the parsing if the journal file doens't exist at all
+ if _, err := os.Stat(journal.path); os.IsNotExist(err) {
+ return nil
+ }
+ // Open the journal for loading any past transactions
+ input, err := os.Open(journal.path)
+ if err != nil {
+ return err
+ }
+ defer input.Close()
+
+ // Temporarily discard any journal additions (don't double add on load)
+ journal.writer = new(devNull)
+ defer func() { journal.writer = nil }()
+
+ // Inject all transactions from the journal into the pool
+ stream := rlp.NewStream(input, 0)
+ total, dropped := 0, 0
+
+ var failure error
+ for {
+ // Parse the next transaction and terminate on error
+ tx := new(types.LendingTransaction)
+ if err = stream.Decode(tx); err != nil {
+ if err != io.EOF {
+ failure = err
+ }
+ break
+ }
+ // Import the transaction and bump the appropriate progress counters
+ total++
+ if err = add(tx); err != nil {
+ log.Debug("Failed to add journaled transaction", "err", err)
+ dropped++
+ continue
+ }
+ }
+ log.Info("Loaded local transaction journal", "transactions", total, "dropped", dropped)
+
+ return failure
+}
+
+// insert adds the specified transaction to the local disk journal.
+func (journal *lendingtxJournal) insert(tx *types.LendingTransaction) error {
+ if journal.writer == nil {
+ return errNoActiveJournal
+ }
+ if err := rlp.Encode(journal.writer, tx); err != nil {
+ return err
+ }
+ return nil
+}
+
+// rotate regenerates the transaction journal based on the current contents of
+// the transaction pool.
+func (journal *lendingtxJournal) rotate(all map[common.Address]types.LendingTransactions) error {
+ // Close the current journal (if any is open)
+ if journal.writer != nil {
+ if err := journal.writer.Close(); err != nil {
+ return err
+ }
+ journal.writer = nil
+ }
+ // Generate a new journal with the contents of the current pool
+ replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
+ if err != nil {
+ return err
+ }
+ journaled := 0
+ for _, txs := range all {
+ for _, tx := range txs {
+ if err = rlp.Encode(replacement, tx); err != nil {
+ replacement.Close()
+ return err
+ }
+ }
+ journaled += len(txs)
+ }
+ replacement.Close()
+
+ // Replace the live journal with the newly generated one
+ if err = os.Rename(journal.path+".new", journal.path); err != nil {
+ return err
+ }
+ sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0755)
+ if err != nil {
+ return err
+ }
+ journal.writer = sink
+ log.Info("Regenerated local transaction journal", "transactions", journaled, "accounts", len(all))
+
+ return nil
+}
+
+// close flushes the transaction journal contents to disk and closes the file.
+func (journal *lendingtxJournal) close() error {
+ var err error
+
+ if journal.writer != nil {
+ err = journal.writer.Close()
+ journal.writer = nil
+ }
+ return err
+}
diff --git a/core/lending_tx_list.go b/core/lending_tx_list.go
new file mode 100644
index 0000000000..5d25ac47ef
--- /dev/null
+++ b/core/lending_tx_list.go
@@ -0,0 +1,289 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "container/heap"
+ "sort"
+
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+)
+
+// txSortedMap is a nonce->transaction hash map with a heap based index to allow
+// iterating over the contents in a nonce-incrementing way.
+type lendingtxSortedMap struct {
+ items map[uint64]*types.LendingTransaction // Hash map storing the transaction data
+ index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
+ cache types.LendingTransactions // Cache of the transactions already sorted
+}
+
+// newTxSortedMap creates a new nonce-sorted transaction map.
+func newLendingTxSortedMap() *lendingtxSortedMap {
+ return &lendingtxSortedMap{
+ items: make(map[uint64]*types.LendingTransaction),
+ index: new(nonceHeap),
+ }
+}
+
+// Get retrieves the current transactions associated with the given nonce.
+func (m *lendingtxSortedMap) Get(nonce uint64) *types.LendingTransaction {
+ return m.items[nonce]
+}
+
+// Put inserts a new transaction into the map, also updating the map's nonce
+// index. If a transaction already exists with the same nonce, it's overwritten.
+func (m *lendingtxSortedMap) Put(tx *types.LendingTransaction) {
+ nonce := tx.Nonce()
+ if m.items[nonce] == nil {
+ heap.Push(m.index, nonce)
+ }
+ m.items[nonce], m.cache = tx, nil
+}
+
+// Forward removes all transactions from the map with a nonce lower than the
+// provided threshold. Every removed transaction is returned for any post-removal
+// maintenance.
+func (m *lendingtxSortedMap) Forward(threshold uint64) types.LendingTransactions {
+ var removed types.LendingTransactions
+
+ // Pop off heap items until the threshold is reached
+ for m.index.Len() > 0 && (*m.index)[0] < threshold {
+ nonce := heap.Pop(m.index).(uint64)
+ removed = append(removed, m.items[nonce])
+ delete(m.items, nonce)
+ }
+ // If we had a cached lending transaction, shift the front
+ if m.cache != nil {
+ m.cache = m.cache[len(removed):]
+ }
+ return removed
+}
+
+// Filter iterates over the list of transactions and removes all of them for which
+// the specified function evaluates to true.
+func (m *lendingtxSortedMap) Filter(filter func(*types.LendingTransaction) bool) types.LendingTransactions {
+ var removed types.LendingTransactions
+
+ // Collect all the transactions to filter out
+ for nonce, tx := range m.items {
+ if filter(tx) {
+ removed = append(removed, tx)
+ delete(m.items, nonce)
+ }
+ }
+ // If transactions were removed, the heap and cache are ruined
+ if len(removed) > 0 {
+ *m.index = make([]uint64, 0, len(m.items))
+ for nonce := range m.items {
+ *m.index = append(*m.index, nonce)
+ }
+ heap.Init(m.index)
+
+ m.cache = nil
+ }
+ return removed
+}
+
+// Cap places a hard limit on the number of items, returning all transactions
+// exceeding that limit.
+func (m *lendingtxSortedMap) Cap(threshold int) types.LendingTransactions {
+ // Short circuit if the number of items is under the limit
+ if len(m.items) <= threshold {
+ return nil
+ }
+ // Otherwise gather and drop the highest nonce'd transactions
+ var drops types.LendingTransactions
+
+ sort.Sort(*m.index)
+ for size := len(m.items); size > threshold; size-- {
+ drops = append(drops, m.items[(*m.index)[size-1]])
+ delete(m.items, (*m.index)[size-1])
+ }
+ *m.index = (*m.index)[:threshold]
+ heap.Init(m.index)
+
+ // If we had a cache, shift the back
+ if m.cache != nil {
+ m.cache = m.cache[:len(m.cache)-len(drops)]
+ }
+ return drops
+}
+
+// Remove deletes a transaction from the maintained map, returning whether the
+// transaction was found.
+func (m *lendingtxSortedMap) Remove(nonce uint64) bool {
+ // Short circuit if no transaction is present
+ _, ok := m.items[nonce]
+ if !ok {
+ return false
+ }
+ // Otherwise delete the transaction and fix the heap index
+ for i := 0; i < m.index.Len(); i++ {
+ if (*m.index)[i] == nonce {
+ heap.Remove(m.index, i)
+ break
+ }
+ }
+ delete(m.items, nonce)
+ m.cache = nil
+
+ return true
+}
+
+// Ready retrieves a sequentially increasing list of transactions starting at the
+// provided nonce that is ready for processing. The returned transactions will be
+// removed from the list.
+//
+// Note, all transactions with nonces lower than start will also be returned to
+// prevent getting into and invalid state. This is not something that should ever
+// happen but better to be self correcting than failing!
+func (m *lendingtxSortedMap) Ready(start uint64) types.LendingTransactions {
+ // Short circuit if no transactions are available
+ if m.index.Len() == 0 || (*m.index)[0] > start {
+ return nil
+ }
+ // Otherwise start accumulating incremental transactions
+ var ready types.LendingTransactions
+ for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
+ ready = append(ready, m.items[next])
+ delete(m.items, next)
+ heap.Pop(m.index)
+ }
+ m.cache = nil
+
+ return ready
+}
+
+// Len returns the length of the transaction map.
+func (m *lendingtxSortedMap) Len() int {
+ return len(m.items)
+}
+
+// Flatten creates a nonce-sorted slice of transactions based on the loosely
+// sorted internal representation. The result of the sorting is cached in case
+// it's requested again before any modifications are made to the contents.
+func (m *lendingtxSortedMap) Flatten() types.LendingTransactions {
+ // If the sorting was not cached yet, create and cache it
+ if m.cache == nil {
+ m.cache = make(types.LendingTransactions, 0, len(m.items))
+ for _, tx := range m.items {
+ m.cache = append(m.cache, tx)
+ }
+ sort.Sort(types.LendingTxByNonce(m.cache))
+ }
+ // Copy the cache to prevent accidental modifications
+ txs := make(types.LendingTransactions, len(m.cache))
+ copy(txs, m.cache)
+ return txs
+}
+
+// txList is a "list" of transactions belonging to an account, sorted by account
+// nonce. The same type can be used both for storing contiguous transactions for
+// the executable/pending queue; and for storing gapped transactions for the non-
+// executable/future queue, with minor behavioral changes.
+type lendingtxList struct {
+ strict bool // Whether nonces are strictly continuous or not
+ txs *lendingtxSortedMap // Heap indexed sorted hash map of the transactions
+}
+
+// newTxList create a new transaction list for maintaining nonce-indexable fast,
+// gapped, sortable transaction lists.
+func newLendingTxList(strict bool) *lendingtxList {
+ return &lendingtxList{
+ strict: strict,
+ txs: newLendingTxSortedMap(),
+ }
+}
+
+// Overlaps returns whether the transaction specified has the same nonce as one
+// already contained within the list.
+func (l *lendingtxList) Overlaps(tx *types.LendingTransaction) bool {
+ return l.txs.Get(tx.Nonce()) != nil
+}
+
+// Add tries to insert a new transaction into the list, returning whether the
+// transaction was accepted, and if yes, any previous transaction it replaced.
+//
+// If the new transaction is accepted into the list, the lists' cost and gas
+// thresholds are also potentially updated.
+func (l *lendingtxList) Add(tx *types.LendingTransaction) (bool, *types.LendingTransaction) {
+ // If there's an older better transaction, abort
+ old := l.txs.Get(tx.Nonce())
+ if old != nil {
+ l.txs.Put(tx)
+ return true, old
+ }
+ l.txs.Put(tx)
+ return true, nil
+}
+
+// Forward removes all transactions from the list with a nonce lower than the
+// provided threshold. Every removed transaction is returned for any post-removal
+// maintenance.
+func (l *lendingtxList) Forward(threshold uint64) types.LendingTransactions {
+ return l.txs.Forward(threshold)
+}
+
+// Cap places a hard limit on the number of items, returning all transactions
+// exceeding that limit.
+func (l *lendingtxList) Cap(threshold int) types.LendingTransactions {
+ return l.txs.Cap(threshold)
+}
+
+// Remove deletes a transaction from the maintained list, returning whether the
+// transaction was found, and also returning any transaction invalidated due to
+// the deletion (strict mode only).
+func (l *lendingtxList) Remove(tx *types.LendingTransaction) (bool, types.LendingTransactions) {
+ // Remove the transaction from the set
+ nonce := tx.Nonce()
+ if removed := l.txs.Remove(nonce); !removed {
+ return false, nil
+ }
+ // In strict mode, filter out non-executable transactions
+ if l.strict {
+ return true, l.txs.Filter(func(tx *types.LendingTransaction) bool { return tx.Nonce() > nonce })
+ }
+ return true, nil
+}
+
+// Ready retrieves a sequentially increasing list of transactions starting at the
+// provided nonce that is ready for processing. The returned transactions will be
+// removed from the list.
+//
+// Note, all transactions with nonces lower than start will also be returned to
+// prevent getting into and invalid state. This is not something that should ever
+// happen but better to be self correcting than failing!
+func (l *lendingtxList) Ready(start uint64) types.LendingTransactions {
+ return l.txs.Ready(start)
+}
+
+// Len returns the length of the transaction list.
+func (l *lendingtxList) Len() int {
+ return l.txs.Len()
+}
+
+// Empty returns whether the list of transactions is empty or not.
+func (l *lendingtxList) Empty() bool {
+ return l.Len() == 0
+}
+
+// Flatten creates a nonce-sorted slice of transactions based on the loosely
+// sorted internal representation. The result of the sorting is cached in case
+// it's requested again before any modifications are made to the contents.
+func (l *lendingtxList) Flatten() types.LendingTransactions {
+ return l.txs.Flatten()
+}
diff --git a/core/mkalloc.go b/core/mkalloc.go
index 565e8c5826..6bc4e55d89 100644
--- a/core/mkalloc.go
+++ b/core/mkalloc.go
@@ -34,8 +34,8 @@ import (
"sort"
"strconv"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
type allocItem struct{ Addr, Balance *big.Int }
diff --git a/core/order_pool.go b/core/order_pool.go
new file mode 100644
index 0000000000..6b36f03050
--- /dev/null
+++ b/core/order_pool.go
@@ -0,0 +1,1081 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+ "gopkg.in/karalabe/cookiejar.v2/collections/prque"
+)
+
+var (
+ // ErrInvalidOrderFormat is returned if the order transaction contains an invalid field.
+ ErrInvalidOrderFormat = errors.New("invalid order format")
+ ErrInvalidOrderContent = errors.New("invalid order content")
+ ErrInvalidOrderSide = errors.New("invalid order side")
+ ErrInvalidOrderType = errors.New("invalid order type")
+ ErrInvalidOrderStatus = errors.New("invalid order status")
+ ErrInvalidOrderUserAddress = errors.New("invalid order user address")
+ ErrInvalidOrderQuantity = errors.New("invalid order quantity")
+ ErrInvalidOrderPrice = errors.New("invalid order price")
+ ErrInvalidOrderHash = errors.New("invalid order hash")
+ ErrInvalidCancelledOrder = errors.New("invalid cancel orderid")
+)
+
+var (
+ OrderTypeLimit = "LO"
+ OrderTypeMarket = "MO"
+ OrderStatusNew = "NEW"
+ OrderStatusCancle = "CANCELLED"
+ OrderSideBid = "BUY"
+ OrderSideAsk = "SELL"
+)
+
+var (
+ ErrPendingNonceTooLow = errors.New("pending nonce too low")
+ ErrPoolOverflow = errors.New("Exceed pool size")
+)
+
+// OrderPoolConfig are the configuration parameters of the order transaction pool.
+type OrderPoolConfig struct {
+ NoLocals bool // Whether local transaction handling should be disabled
+ Journal string // Journal of local transactions to survive node restarts
+ Rejournal time.Duration // Time interval to regenerate the local transaction journal
+
+ AccountSlots uint64 // Minimum number of executable transaction slots guaranteed per account
+ GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts
+ AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
+ GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts
+
+ Lifetime time.Duration // Maximum amount of time non-executable transaction are queued
+}
+
+// blockChain_XDCx add order state
+type blockChainXDCx interface {
+ CurrentBlock() *types.Block
+ GetBlock(hash common.Hash, number uint64) *types.Block
+ OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error)
+ StateAt(root common.Hash) (*state.StateDB, error)
+ SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
+ Engine() consensus.Engine
+ // GetHeader returns the hash corresponding to their hash.
+ GetHeader(common.Hash, uint64) *types.Header
+ // CurrentHeader retrieves the current header from the local chain.
+ CurrentHeader() *types.Header
+ // Config retrieves the blockchain's chain configuration.
+ Config() *params.ChainConfig
+}
+
+// DefaultOrderPoolConfig contains the default configurations for the transaction
+// pool.
+var DefaultOrderPoolConfig = OrderPoolConfig{
+ Journal: "",
+ Rejournal: time.Hour,
+
+ AccountSlots: 16,
+ GlobalSlots: 4096,
+ AccountQueue: 64,
+ GlobalQueue: 1024,
+
+ Lifetime: 3 * time.Hour,
+}
+
+// sanitize checks the provided user configurations and changes anything that's
+// unreasonable or unworkable.
+func (config *OrderPoolConfig) sanitize() OrderPoolConfig {
+ conf := *config
+ if conf.Rejournal < time.Second {
+ log.Warn("Sanitizing invalid OrderPool journal time", "provided", conf.Rejournal, "updated", time.Second)
+ conf.Rejournal = time.Second
+ }
+ return conf
+}
+
+// OrderPool contains all currently known transactions. Transactions
+// enter the pool when they are received from the network or submitted
+// locally. They exit the pool when they are included in the blockchain.
+//
+// The pool separates processable transactions (which can be applied to the
+// current state) and future transactions. Transactions move between those
+// two states over time as they are received and processed.
+type OrderPool struct {
+ config OrderPoolConfig
+ chainconfig *params.ChainConfig
+ chain blockChainXDCx
+
+ txFeed event.Feed
+ scope event.SubscriptionScope
+ chainHeadCh chan ChainHeadEvent
+ chainHeadSub event.Subscription
+ signer types.OrderSigner
+ mu sync.RWMutex
+
+ currentRootState *state.StateDB
+ currentOrderState *tradingstate.TradingStateDB // Current order state in the blockchain head
+ pendingState *tradingstate.XDCXManagedState // Pending state tracking virtual nonces
+
+ locals *orderAccountSet // Set of local transaction to exempt from eviction rules
+ journal *ordertxJournal // Journal of local transaction to back up to disk
+
+ pending map[common.Address]*ordertxList // All currently processable transactions
+ queue map[common.Address]*ordertxList // Queued but non-processable transactions
+ beats map[common.Address]time.Time // Last heartbeat from each known account
+ all map[common.Hash]*types.OrderTransaction // All transactions to allow lookups
+ wg sync.WaitGroup // for shutdown sync
+ homestead bool
+ IsSigner func(address common.Address) bool
+}
+
+// NewOrderPool creates a new transaction pool to gather, sort and filter inbound
+// transactions from the network.
+func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderPool {
+ // Sanitize the input to ensure no vulnerable gas prices are set
+ config := (&DefaultOrderPoolConfig).sanitize()
+ log.Debug("NewOrderPool start...", "current block", chain.CurrentBlock().Header().Number)
+ // Create the transaction pool with its initial settings
+ pool := &OrderPool{
+ config: config,
+ chainconfig: chainconfig,
+ chain: chain,
+ signer: types.OrderTxSigner{},
+ pending: make(map[common.Address]*ordertxList),
+ queue: make(map[common.Address]*ordertxList),
+ beats: make(map[common.Address]time.Time),
+ all: make(map[common.Hash]*types.OrderTransaction),
+ chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
+ }
+ pool.locals = newOrderAccountSet(pool.signer)
+ pool.reset(nil, chain.CurrentBlock())
+
+ // If local transactions and journaling is enabled, load from disk
+ if !config.NoLocals && config.Journal != "" {
+ pool.journal = newOrderTxJournal(config.Journal)
+
+ if err := pool.journal.load(pool.AddLocal); err != nil {
+ log.Warn("Failed to load transaction journal", "err", err)
+ }
+ if err := pool.journal.rotate(pool.local()); err != nil {
+ log.Warn("Failed to rotate transaction journal", "err", err)
+ }
+ }
+ // Subscribe events from blockchain
+ pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
+
+ // Start the event loop and return
+ pool.wg.Add(1)
+ go pool.loop()
+
+ return pool
+}
+
+// loop is the transaction pool's main event loop, waiting for and reacting to
+// outside blockchain events as well as for various reporting and transaction
+// eviction events.
+func (pool *OrderPool) loop() {
+ defer pool.wg.Done()
+
+ // Start the stats reporting and transaction eviction tickers
+
+ report := time.NewTicker(statsReportInterval)
+ defer report.Stop()
+
+ evict := time.NewTicker(evictionInterval)
+ defer evict.Stop()
+
+ journal := time.NewTicker(pool.config.Rejournal)
+ defer journal.Stop()
+
+ // Track the previous head headers for transaction reorgs
+ head := pool.chain.CurrentBlock()
+
+ // Keep waiting for and reacting to the various events
+ for {
+ select {
+ // Handle ChainHeadEvent
+ case ev := <-pool.chainHeadCh:
+ if ev.Block != nil {
+ pool.mu.Lock()
+ if pool.chainconfig.IsHomestead(ev.Block.Number()) {
+ pool.homestead = true
+ }
+ log.Debug("OrderPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
+ pool.reset(head, ev.Block)
+ head = ev.Block
+
+ pool.mu.Unlock()
+ }
+ // Be unsubscribed due to system stopped
+ case <-pool.chainHeadSub.Err():
+ return
+
+ // Handle stats reporting ticks
+ case <-report.C:
+ pool.mu.RLock()
+ pending, queued := pool.stats()
+ pool.mu.RUnlock()
+
+ log.Debug("Order pool status report", "executable", pending, "queued", queued)
+
+ // Handle inactive account transaction eviction
+ case <-evict.C:
+ pool.mu.Lock()
+ for addr := range pool.queue {
+ // Skip local transactions from the eviction mechanism
+ if pool.locals.contains(addr) {
+ continue
+ }
+ // Any non-locals old enough should be removed
+ if time.Since(pool.beats[addr]) > pool.config.Lifetime {
+ for _, tx := range pool.queue[addr].Flatten() {
+ pool.removeTx(tx.Hash())
+ }
+ }
+ }
+ pool.mu.Unlock()
+
+ // Handle local transaction journal rotation
+ case <-journal.C:
+ if pool.journal != nil {
+ pool.mu.Lock()
+ if err := pool.journal.rotate(pool.local()); err != nil {
+ log.Warn("Failed to rotate local tx journal", "err", err)
+ }
+ pool.mu.Unlock()
+ }
+ }
+ }
+}
+
+// reset retrieves the current state of the blockchain and ensures the content
+// of the transaction pool is valid with regard to the chain state.
+func (pool *OrderPool) reset(oldHead, newblock *types.Block) {
+ if !pool.chainconfig.IsTIPXDCX(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
+ return
+ }
+ // If we're reorging an old state, reinject all dropped transactions
+ var reinject types.OrderTransactions
+
+ // Initialize the internal state to the current head
+ if newblock == nil {
+ newblock = pool.chain.CurrentBlock()
+ }
+ newHead := newblock.Header()
+ orderstate, err := pool.chain.OrderStateAt(newblock)
+ if err != nil {
+ log.Error("Failed to reset OrderPool state", "err", err)
+ return
+ }
+ pool.currentOrderState = orderstate
+ pool.pendingState = tradingstate.ManageState(orderstate)
+
+ state, err := pool.chain.StateAt(newHead.Root)
+ if err != nil {
+ log.Error("Failed to reset pool state", "err", err)
+ return
+ }
+ pool.currentRootState = state
+
+ // Inject any transactions discarded due to reorgs
+ log.Debug("Reinjecting stale transactions", "count", len(reinject))
+ pool.addTxsLocked(reinject, false)
+
+ // validate the pool of pending transactions, this will remove
+ // any transactions that have been included in the block or
+ // have been invalidated because of another transaction (e.g.
+ // higher gas price)
+ pool.demoteUnexecutables()
+
+ // Update all accounts to the latest known pending nonce
+ for addr, list := range pool.pending {
+ txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
+ pool.pendingState.SetNonce(addr.Hash(), txs[len(txs)-1].Nonce()+1)
+ }
+ // Check the queue and move transactions over to the pending if possible
+ // or remove those that have become invalid
+ pool.promoteExecutables(nil)
+}
+
+// Stop terminates the transaction pool.
+func (pool *OrderPool) Stop() {
+ // Unsubscribe all subscriptions registered from OrderPool
+ pool.scope.Close()
+
+ // Unsubscribe subscriptions registered from blockchain
+ pool.chainHeadSub.Unsubscribe()
+ pool.wg.Wait()
+
+ if pool.journal != nil {
+ pool.journal.close()
+ }
+ log.Info("Transaction pool stopped")
+}
+
+// SubscribeTxPreEvent registers a subscription of TxPreEvent and
+// starts sending event to the given channel.
+func (pool *OrderPool) SubscribeTxPreEvent(ch chan<- OrderTxPreEvent) event.Subscription {
+ return pool.scope.Track(pool.txFeed.Subscribe(ch))
+}
+
+// State returns the virtual managed state of the transaction pool.
+func (pool *OrderPool) State() *tradingstate.XDCXManagedState {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.pendingState
+}
+
+// Stats retrieves the current pool stats, namely the number of pending and the
+// number of queued (non-executable) transactions.
+func (pool *OrderPool) Stats() (int, int) {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.stats()
+}
+
+// stats retrieves the current pool stats, namely the number of pending and the
+// number of queued (non-executable) transactions.
+func (pool *OrderPool) stats() (int, int) {
+ pending := 0
+ for _, list := range pool.pending {
+ pending += list.Len()
+ }
+ queued := 0
+ for _, list := range pool.queue {
+ queued += list.Len()
+ }
+ return pending, queued
+}
+
+// Content retrieves the data content of the transaction pool, returning all the
+// pending as well as queued transactions, grouped by account and sorted by nonce.
+func (pool *OrderPool) Content() (map[common.Address]types.OrderTransactions, map[common.Address]types.OrderTransactions) {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ pending := make(map[common.Address]types.OrderTransactions)
+ for addr, list := range pool.pending {
+ pending[addr] = list.Flatten()
+ }
+ queued := make(map[common.Address]types.OrderTransactions)
+ for addr, list := range pool.queue {
+ queued[addr] = list.Flatten()
+ }
+ return pending, queued
+}
+
+// Pending retrieves all currently processable transactions, groupped by origin
+// account and sorted by nonce. The returned transaction set is a copy and can be
+// freely modified by calling code.
+func (pool *OrderPool) Pending() (map[common.Address]types.OrderTransactions, error) {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ pending := make(map[common.Address]types.OrderTransactions)
+ for addr, list := range pool.pending {
+ pending[addr] = list.Flatten()
+ }
+ return pending, nil
+}
+
+// local retrieves all currently known local transactions, groupped by origin
+// account and sorted by nonce. The returned transaction set is a copy and can be
+// freely modified by calling code.
+func (pool *OrderPool) local() map[common.Address]types.OrderTransactions {
+ txs := make(map[common.Address]types.OrderTransactions)
+ for addr := range pool.locals.accounts {
+ if pending := pool.pending[addr]; pending != nil {
+ txs[addr] = append(txs[addr], pending.Flatten()...)
+ }
+ if queued := pool.queue[addr]; queued != nil {
+ txs[addr] = append(txs[addr], queued.Flatten()...)
+ }
+ }
+ return txs
+}
+
+// GetSender get sender from transaction
+func (pool *OrderPool) GetSender(tx *types.OrderTransaction) (common.Address, error) {
+ from, err := types.OrderSender(pool.signer, tx)
+ if err != nil {
+ return common.Address{}, ErrInvalidSender
+ }
+ return from, nil
+}
+
+func (pool *OrderPool) validateOrder(tx *types.OrderTransaction) error {
+ orderSide := tx.Side()
+ orderType := tx.Type()
+ orderStatus := tx.Status()
+ price := tx.Price()
+ quantity := tx.Quantity()
+
+ cloneStateDb := pool.currentRootState.Copy()
+ cloneXDCXStateDb := pool.currentOrderState.Copy()
+
+ if !tx.IsCancelledOrder() {
+ if quantity == nil || quantity.Cmp(big.NewInt(0)) <= 0 {
+ return ErrInvalidOrderQuantity
+ }
+ if orderType != OrderTypeMarket {
+ if price == nil || price.Cmp(big.NewInt(0)) <= 0 {
+ return ErrInvalidOrderPrice
+ }
+ }
+
+ if orderSide != OrderSideAsk && orderSide != OrderSideBid {
+ return ErrInvalidOrderSide
+ }
+ if orderType != OrderTypeLimit && orderType != OrderTypeMarket {
+ return ErrInvalidOrderType
+ }
+ if err := tradingstate.VerifyPair(cloneStateDb, tx.ExchangeAddress(), tx.BaseToken(), tx.QuoteToken()); err != nil {
+ return err
+ }
+
+ if orderType == OrderTypeLimit {
+ XDPoSEngine, ok := pool.chain.Engine().(*XDPoS.XDPoS)
+ if !ok {
+ return ErrNotXDPoS
+ }
+ XDCXServ := XDPoSEngine.GetXDCXService()
+ if XDCXServ == nil {
+ return fmt.Errorf("XDCx not found in order validation")
+ }
+ baseDecimal, err := XDCXServ.GetTokenDecimal(pool.chain, cloneStateDb, tx.BaseToken())
+ if err != nil {
+ return fmt.Errorf("validateOrder: failed to get baseDecimal. err: %v", err)
+ }
+ quoteDecimal, err := XDCXServ.GetTokenDecimal(pool.chain, cloneStateDb, tx.QuoteToken())
+ if err != nil {
+ return fmt.Errorf("validateOrder: failed to get quoteDecimal. err: %v", err)
+ }
+ if err := tradingstate.VerifyBalance(cloneStateDb, cloneXDCXStateDb, tx, baseDecimal, quoteDecimal); err != nil {
+ return err
+ }
+ }
+
+ }
+
+ if orderStatus != OrderStatusNew && orderStatus != OrderStatusCancle {
+ return ErrInvalidOrderStatus
+ }
+ var signer = types.OrderTxSigner{}
+
+ if !tx.IsCancelledOrder() {
+ if !common.EmptyHash(tx.OrderHash()) {
+ if signer.Hash(tx) != tx.OrderHash() {
+ return ErrInvalidOrderHash
+ }
+ } else {
+ tx.SetOrderHash(signer.Hash(tx))
+ }
+
+ } else {
+ if tx.OrderID() == 0 {
+ return ErrInvalidCancelledOrder
+ }
+ originOrder := cloneXDCXStateDb.GetOrder(tradingstate.GetTradingOrderBookHash(tx.BaseToken(), tx.QuoteToken()), common.BigToHash(new(big.Int).SetUint64(tx.OrderID())))
+ if originOrder == tradingstate.EmptyOrder {
+ log.Debug("Order not found ", "OrderId", tx.OrderID(), "BaseToken", tx.BaseToken().Hex(), "QuoteToken", tx.QuoteToken().Hex())
+ return ErrInvalidCancelledOrder
+ }
+ if originOrder.Hash != tx.OrderHash() {
+ log.Debug("Invalid order hash", "expected", originOrder.Hash.Hex(), "got", tx.OrderHash().Hex())
+ return ErrInvalidOrderHash
+ }
+ }
+
+ from, _ := types.OrderSender(pool.signer, tx)
+ if from != tx.UserAddress() {
+ return ErrInvalidOrderUserAddress
+ }
+
+ if !tradingstate.IsValidRelayer(cloneStateDb, tx.ExchangeAddress()) {
+ return fmt.Errorf("invalid relayer. ExchangeAddress: %s", tx.ExchangeAddress().Hex())
+ }
+
+ return nil
+}
+
+// validateTx checks whether a transaction is valid according to the consensus
+// rules and adheres to some heuristic limits of the local node (price and size).
+func (pool *OrderPool) validateTx(tx *types.OrderTransaction, local bool) error {
+
+ // check if sender is in black list
+ if tx.From() != nil && common.Blacklist[*tx.From()] {
+ return fmt.Errorf("Reject transaction with sender in black-list: %v", tx.From().Hex())
+ }
+ // Heuristic limit, reject transactions over 32KB to prevent DOS attacks
+ if tx.Size() > 32*1024 {
+ return ErrOversizedData
+ }
+
+ // Make sure the transaction is signed properly
+ from, err := types.OrderSender(pool.signer, tx)
+ if err != nil {
+ return ErrInvalidSender
+ }
+ err = pool.validateOrder(tx)
+ if err != nil {
+ return err
+ }
+ // Ensure the transaction adheres to nonce ordering
+ if pool.currentOrderState.GetNonce(from.Hash()) > tx.Nonce() {
+ return ErrNonceTooLow
+ }
+ if pool.pendingState.GetNonce(from.Hash())+common.LimitThresholdNonceInQueue < tx.Nonce() {
+ return ErrNonceTooHigh
+ }
+
+ return nil
+}
+
+// add validates a transaction and inserts it into the non-executable queue for
+// later pending promotion and execution. If the transaction is a replacement for
+// an already pending or queued one, it overwrites the previous and returns this
+// so outer code doesn't uselessly call promote.
+//
+// If a newly added transaction is marked as local, its sending account will be
+// whitelisted, preventing any associated transaction from being dropped out of
+// the pool due to pricing constraints.
+func (pool *OrderPool) add(tx *types.OrderTransaction, local bool) (bool, error) {
+ // If the transaction is already known, discard it
+ hash := tx.Hash()
+ if pool.all[hash] != nil {
+ log.Debug("Discarding known order transaction", "hash", hash, "userAddress", tx.UserAddress().Hex(), "status", tx.Status)
+ return false, fmt.Errorf("known transaction: %x", hash)
+ }
+
+ // If the transaction fails basic validation, discard it
+ if err := pool.validateTx(tx, local); err != nil {
+ log.Debug("Discarding invalid order transaction", "hash", hash, "userAddress", tx.UserAddress().Hex(), "status", tx.Status, "err", err)
+ invalidTxCounter.Inc(1)
+ return false, err
+ }
+ from, _ := types.OrderSender(pool.signer, tx) // already validated
+
+ // If the transaction pool is full, discard underpriced transactions
+ if uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
+ log.Debug("Add order transaction to pool full", "hash", hash, "nonce", tx.Nonce())
+ return false, ErrPoolOverflow
+ }
+ // If the transaction is replacing an already pending one, do directly
+ if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
+ inserted, old := list.Add(tx)
+ if !inserted {
+ pendingDiscardCounter.Inc(1)
+ return false, ErrPendingNonceTooLow
+ }
+ if old != nil {
+ delete(pool.all, old.Hash())
+ pendingReplaceCounter.Inc(1)
+ }
+ pool.all[tx.Hash()] = tx
+ pool.journalTx(from, tx)
+
+ log.Debug("Pooled new executable transaction", "hash", hash, "useraddress", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "status", tx.Status(), "orderid", tx.OrderID())
+ go pool.txFeed.Send(OrderTxPreEvent{tx})
+ return old != nil, nil
+
+ }
+ // New transaction isn't replacing a pending one, push into queue
+ replace, err := pool.enqueueTx(hash, tx)
+ if err != nil {
+ return false, err
+ }
+ // Mark local addresses and journal local transactions
+ if local {
+ pool.locals.add(from)
+ }
+ pool.journalTx(from, tx)
+
+ log.Debug("Pooled new future transaction", "hash", hash, "from", from)
+ return replace, nil
+}
+
+// enqueueTx inserts a new transaction into the non-executable transaction queue.
+//
+// Note, this method assumes the pool lock is held!
+func (pool *OrderPool) enqueueTx(hash common.Hash, tx *types.OrderTransaction) (bool, error) {
+ // Try to insert the transaction into the future queue
+ log.Debug("enqueueTx", "hash", hash, "useraddress", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "status", tx.Status(), "orderid", tx.OrderID())
+ from, _ := types.OrderSender(pool.signer, tx) // already validated
+ if pool.queue[from] == nil {
+ pool.queue[from] = newOrderTxList(false)
+ }
+ inserted, old := pool.queue[from].Add(tx)
+ if !inserted {
+ // An older transaction was better, discard this
+ queuedDiscardCounter.Inc(1)
+ return false, ErrPendingNonceTooLow
+ }
+ // Discard any previous transaction and mark this
+ if old != nil {
+ delete(pool.all, old.Hash())
+ queuedReplaceCounter.Inc(1)
+ }
+ pool.all[hash] = tx
+ return old != nil, nil
+}
+
+// journalTx adds the specified transaction to the local disk journal if it is
+// deemed to have been sent from a local account.
+func (pool *OrderPool) journalTx(from common.Address, tx *types.OrderTransaction) {
+ // Only journal if it's enabled and the transaction is local
+ if pool.journal == nil || !pool.locals.contains(from) {
+ return
+ }
+ if err := pool.journal.insert(tx); err != nil {
+ log.Warn("Failed to journal local transaction", "err", err)
+ }
+}
+
+// promoteTx adds a transaction to the pending (processable) list of transactions.
+//
+// Note, this method assumes the pool lock is held!
+func (pool *OrderPool) promoteTx(addr common.Address, hash common.Hash, tx *types.OrderTransaction) {
+ // Try to insert the transaction into the pending queue
+ log.Debug("promoteTx", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ if pool.pending[addr] == nil {
+ pool.pending[addr] = newOrderTxList(true)
+ }
+ list := pool.pending[addr]
+
+ inserted, old := list.Add(tx)
+ if !inserted {
+ // An older transaction was better, discard this
+ delete(pool.all, hash)
+ pendingDiscardCounter.Inc(1)
+ return
+ }
+ // Otherwise discard any previous transaction and mark this
+ if old != nil {
+ delete(pool.all, old.Hash())
+ pendingReplaceCounter.Inc(1)
+ }
+ // Failsafe to work around direct pending inserts (tests)
+ if pool.all[hash] == nil {
+ pool.all[hash] = tx
+ }
+ // Set the potentially new pending nonce and notify any subsystems of the new tx
+ pool.beats[addr] = time.Now()
+ pool.pendingState.SetNonce(addr.Hash(), tx.Nonce()+1)
+ log.Debug("promoteTx txFeed.Send", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ go pool.txFeed.Send(OrderTxPreEvent{tx})
+}
+
+// AddLocal enqueues a single transaction into the pool if it is valid, marking
+// the sender as a local one in the mean time, ensuring it goes around the local
+// pricing constraints.
+func (pool *OrderPool) AddLocal(tx *types.OrderTransaction) error {
+ log.Debug("AddLocal order add local tx", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ return pool.addTx(tx, !pool.config.NoLocals)
+}
+
+// AddRemote enqueues a single transaction into the pool if it is valid. If the
+// sender is not among the locally tracked ones, full pricing constraints will
+// apply.
+func (pool *OrderPool) AddRemote(tx *types.OrderTransaction) error {
+ log.Debug("AddRemote", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ return pool.addTx(tx, false)
+}
+
+// AddLocals enqueues a batch of transactions into the pool if they are valid,
+// marking the senders as a local ones in the mean time, ensuring they go around
+// the local pricing constraints.
+func (pool *OrderPool) AddLocals(txs []*types.OrderTransaction) []error {
+ return pool.addTxs(txs, !pool.config.NoLocals)
+}
+
+// AddRemotes enqueues a batch of transactions into the pool if they are valid.
+// If the senders are not among the locally tracked ones, full pricing constraints
+// will apply.
+func (pool *OrderPool) AddRemotes(txs []*types.OrderTransaction) []error {
+ for _, tx := range txs {
+ log.Debug("AddRemotes", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ }
+ return pool.addTxs(txs, false)
+}
+
+// addTx enqueues a single transaction into the pool if it is valid.
+func (pool *OrderPool) addTx(tx *types.OrderTransaction, local bool) error {
+ if !pool.chainconfig.IsTIPXDCX(pool.chain.CurrentBlock().Number()) {
+ return nil
+ }
+ tx.CacheHash()
+ types.CacheOrderSigner(pool.signer, tx)
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ // Try to inject the transaction and update any state
+ replace, err := pool.add(tx, local)
+ if err != nil {
+ return err
+ }
+ // If we added a new transaction, run promotion checks and return
+ if !replace {
+ from, _ := types.OrderSender(pool.signer, tx) // already validated
+ pool.promoteExecutables([]common.Address{from})
+ }
+ return nil
+}
+
+// addTxs attempts to queue a batch of transactions if they are valid.
+func (pool *OrderPool) addTxs(txs []*types.OrderTransaction, local bool) []error {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+
+ return pool.addTxsLocked(txs, local)
+}
+
+// addTxsLocked attempts to queue a batch of transactions if they are valid,
+// whilst assuming the transaction pool lock is already held.
+func (pool *OrderPool) addTxsLocked(txs []*types.OrderTransaction, local bool) []error {
+ // Add the batch of transaction, tracking the accepted ones
+ dirty := make(map[common.Address]struct{})
+ errs := make([]error, len(txs))
+
+ for i, tx := range txs {
+ var replace bool
+ if replace, errs[i] = pool.add(tx, local); errs[i] == nil {
+ if !replace {
+ from, _ := types.OrderSender(pool.signer, tx) // already validated
+ dirty[from] = struct{}{}
+ }
+ }
+ }
+ // Only reprocess the internal state if something was actually added
+ if len(dirty) > 0 {
+ addrs := make([]common.Address, 0, len(dirty))
+ for addr := range dirty {
+ addrs = append(addrs, addr)
+ }
+ pool.promoteExecutables(addrs)
+ }
+ return errs
+}
+
+// Status returns the status (unknown/pending/queued) of a batch of transactions
+// identified by their hashes.
+func (pool *OrderPool) Status(hashes []common.Hash) []TxStatus {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ status := make([]TxStatus, len(hashes))
+ for i, hash := range hashes {
+ if tx := pool.all[hash]; tx != nil {
+ from, _ := types.OrderSender(pool.signer, tx) // already validated
+ if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil {
+ status[i] = TxStatusPending
+ } else {
+ status[i] = TxStatusQueued
+ }
+ }
+ }
+ return status
+}
+
+// Get returns a transaction if it is contained in the pool
+// and nil otherwise.
+func (pool *OrderPool) Get(hash common.Hash) *types.OrderTransaction {
+ pool.mu.RLock()
+ defer pool.mu.RUnlock()
+
+ return pool.all[hash]
+}
+
+// removeTx removes a single transaction from the queue, moving all subsequent
+// transactions back to the future queue.
+func (pool *OrderPool) removeTx(hash common.Hash) {
+ // Fetch the transaction we wish to delete
+ tx, ok := pool.all[hash]
+ if !ok {
+ return
+ }
+ addr, _ := types.OrderSender(pool.signer, tx) // already validated during insertion
+
+ // Remove it from the list of known transactions
+ delete(pool.all, hash)
+
+ // Remove the transaction from the pending lists and reset the account nonce
+ if pending := pool.pending[addr]; pending != nil {
+ if removed, invalids := pending.Remove(tx); removed {
+ // If no more pending transactions are left, remove the list
+ if pending.Empty() {
+ delete(pool.pending, addr)
+ delete(pool.beats, addr)
+ }
+ // Postpone any invalidated transactions
+ for _, tx := range invalids {
+ pool.enqueueTx(tx.Hash(), tx)
+ }
+ // Update the account nonce if needed
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr.Hash()) > nonce {
+ pool.pendingState.SetNonce(addr.Hash(), nonce)
+ }
+ return
+ }
+ }
+ // Transaction is in the future queue
+ if future := pool.queue[addr]; future != nil {
+ future.Remove(tx)
+ if future.Empty() {
+ delete(pool.queue, addr)
+ }
+ }
+}
+
+// promoteExecutables moves transactions that have become processable from the
+// future queue to the set of pending transactions. During this process, all
+// invalidated transactions (low nonce, low balance) are deleted.
+func (pool *OrderPool) promoteExecutables(accounts []common.Address) {
+ start := time.Now()
+ defer log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start)))
+ // Gather all the accounts potentially needing updates
+ if accounts == nil {
+ accounts = make([]common.Address, 0, len(pool.queue))
+ for addr := range pool.queue {
+ accounts = append(accounts, addr)
+ }
+ }
+ // Iterate over all accounts and promote any executable transactions
+ for _, addr := range accounts {
+ list := pool.queue[addr]
+ if list == nil {
+ continue // Just in case someone calls with a non existing account
+ }
+ // Drop all transactions that are deemed too old (low nonce)
+ for _, tx := range list.Forward(pool.currentOrderState.GetNonce(addr.Hash())) {
+ hash := tx.Hash()
+ log.Debug("Removed old queued transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ delete(pool.all, hash)
+
+ }
+
+ // Gather all executable transactions and promote them
+ for _, tx := range list.Ready(pool.pendingState.GetNonce(addr.Hash())) {
+ hash := tx.Hash()
+ log.Debug("Promoting queued transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ pool.promoteTx(addr, hash, tx)
+ }
+ // Drop all transactions over the allowed limit
+ if !pool.locals.contains(addr) {
+ for _, tx := range list.Cap(int(pool.config.AccountQueue)) {
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ queuedRateLimitCounter.Inc(1)
+ log.Debug("Removed cap-exceeding queued transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ }
+ }
+ // Delete the entire queue entry if it became empty.
+ if list.Empty() {
+ log.Debug("promoteExecutables remove transaction queue", "addr", addr.Hex())
+ delete(pool.queue, addr)
+ }
+ }
+ // If the pending limit is overflown, start equalizing allowances
+ pending := uint64(0)
+ for _, list := range pool.pending {
+ pending += uint64(list.Len())
+ }
+ if pending > pool.config.GlobalSlots {
+ pendingBeforeCap := pending
+ // Assemble a spam order to penalize large transactors first
+ spammers := prque.New()
+ for addr, list := range pool.pending {
+ // Only evict transactions from high rollers
+ if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots {
+ spammers.Push(addr, float32(list.Len()))
+ }
+ }
+ // Gradually drop transactions from offenders
+ offenders := []common.Address{}
+ for pending > pool.config.GlobalSlots && !spammers.Empty() {
+ // Retrieve the next offender if not local address
+ offender, _ := spammers.Pop()
+ offenders = append(offenders, offender.(common.Address))
+
+ // Equalize balances until all the same or below threshold
+ if len(offenders) > 1 {
+ // Calculate the equalization threshold for all current offenders
+ threshold := pool.pending[offender.(common.Address)].Len()
+
+ // Iteratively reduce all offenders until below limit or threshold reached
+ for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold {
+ for i := 0; i < len(offenders)-1; i++ {
+ list := pool.pending[offenders[i]]
+ for _, tx := range list.Cap(list.Len() - 1) {
+ // Drop the transaction from the global pools too
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ // Update the account nonce to the dropped transaction
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i].Hash()) > nonce {
+ pool.pendingState.SetNonce(offenders[i].Hash(), nonce)
+ }
+ log.Debug("Removed fairness-exceeding pending transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ }
+ pending--
+ }
+ }
+ }
+ }
+ // If still above threshold, reduce to limit or min allowance
+ if pending > pool.config.GlobalSlots && len(offenders) > 0 {
+ for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots {
+ for _, addr := range offenders {
+ list := pool.pending[addr]
+ for _, tx := range list.Cap(list.Len() - 1) {
+ // Drop the transaction from the global pools too
+ hash := tx.Hash()
+ delete(pool.all, hash)
+
+ // Update the account nonce to the dropped transaction
+ if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr.Hash()) > nonce {
+ pool.pendingState.SetNonce(addr.Hash(), nonce)
+ }
+ log.Debug("Removed fairness-exceeding pending transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ }
+ pending--
+ }
+ }
+ }
+ pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
+ }
+ // If we've queued more transactions than the hard limit, drop oldest ones
+ queued := uint64(0)
+ for _, list := range pool.queue {
+ queued += uint64(list.Len())
+ }
+ if queued > pool.config.GlobalQueue {
+ // Sort all accounts with queued transactions by heartbeat
+ addresses := make(addresssByHeartbeat, 0, len(pool.queue))
+ for addr := range pool.queue {
+ if !pool.locals.contains(addr) { // don't drop locals
+ addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
+ }
+ }
+ sort.Sort(addresses)
+
+ // Drop transactions until the total is below the limit or only locals remain
+ for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; {
+ addr := addresses[len(addresses)-1]
+ list := pool.queue[addr.address]
+
+ addresses = addresses[:len(addresses)-1]
+
+ // Drop all transactions if they are less than the overflow
+ if size := uint64(list.Len()); size <= drop {
+ for _, tx := range list.Flatten() {
+ pool.removeTx(tx.Hash())
+ }
+ drop -= size
+ queuedRateLimitCounter.Inc(int64(size))
+ continue
+ }
+ // Otherwise drop only last few transactions
+ txs := list.Flatten()
+ for i := len(txs) - 1; i >= 0 && drop > 0; i-- {
+ pool.removeTx(txs[i].Hash())
+ drop--
+ queuedRateLimitCounter.Inc(1)
+ }
+ }
+ }
+}
+
+// demoteUnexecutables removes invalid and processed transactions from the pools
+// executable/pending queue and any subsequent transactions that become unexecutable
+// are moved back into the future queue.
+func (pool *OrderPool) demoteUnexecutables() {
+ // Iterate over all accounts and demote any non-executable transactions
+ for addr, list := range pool.pending {
+ nonce := pool.currentOrderState.GetNonce(addr.Hash())
+ log.Debug("demoteUnexecutables", "addr", addr.Hex(), "nonce", nonce)
+ // Drop all transactions that are deemed too old (low nonce)
+ for _, tx := range list.Forward(nonce) {
+ hash := tx.Hash()
+ log.Debug("demoteUnexecutables removed old queued transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ delete(pool.all, hash)
+ }
+
+ // If there's a gap in front, warn (should never happen) and postpone all transactions
+ if list.Len() > 0 && list.txs.Get(nonce) == nil {
+ for _, tx := range list.Cap(0) {
+ hash := tx.Hash()
+ log.Debug("demoteUnexecutables Demoting invalidated transaction", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID())
+ pool.enqueueTx(hash, tx)
+ }
+ }
+ // Delete the entire queue entry if it became empty.
+ if list.Empty() {
+ delete(pool.pending, addr)
+ delete(pool.beats, addr)
+ }
+ }
+}
+
+type orderAccountSet struct {
+ accounts map[common.Address]struct{}
+ signer types.OrderSigner
+}
+
+// newAccountSet creates a new address set with an associated signer for sender
+// derivations.
+func newOrderAccountSet(signer types.OrderSigner) *orderAccountSet {
+ return &orderAccountSet{
+ accounts: make(map[common.Address]struct{}),
+ signer: signer,
+ }
+}
+
+// contains checks if a given address is contained within the set.
+func (as *orderAccountSet) contains(addr common.Address) bool {
+ _, exist := as.accounts[addr]
+ return exist
+}
+
+// containsTx checks if the sender of a given tx is within the set. If the sender
+// cannot be derived, this method returns false.
+func (as *orderAccountSet) containsTx(tx *types.OrderTransaction) bool {
+ if addr, err := types.OrderSender(as.signer, tx); err == nil {
+ return as.contains(addr)
+ }
+ return false
+}
+
+// add inserts a new address into the set to track.
+func (as *orderAccountSet) add(addr common.Address) {
+ as.accounts[addr] = struct{}{}
+}
diff --git a/core/order_pool_test.go b/core/order_pool_test.go
new file mode 100644
index 0000000000..ea11b265bc
--- /dev/null
+++ b/core/order_pool_test.go
@@ -0,0 +1,314 @@
+package core
+
+import (
+ "context"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethclient"
+ "github.com/XinFinOrg/XDPoSChain/rpc"
+ "log"
+ "math/big"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+)
+
+type OrderMsg struct {
+ AccountNonce uint64 `json:"nonce" gencodec:"required"`
+ Quantity *big.Int `json:"quantity,omitempty"`
+ Price *big.Int `json:"price,omitempty"`
+ ExchangeAddress common.Address `json:"exchangeAddress,omitempty"`
+ UserAddress common.Address `json:"userAddress,omitempty"`
+ BaseToken common.Address `json:"baseToken,omitempty"`
+ QuoteToken common.Address `json:"quoteToken,omitempty"`
+ Status string `json:"status,omitempty"`
+ Side string `json:"side,omitempty"`
+ Type string `json:"type,omitempty"`
+ OrderID uint64 `json:"orderid,omitempty"`
+ // Signature values
+ V *big.Int `json:"v" gencodec:"required"`
+ R *big.Int `json:"r" gencodec:"required"`
+ S *big.Int `json:"s" gencodec:"required"`
+
+ // This is only used when marshaling to JSON.
+ Hash common.Hash `json:"hash" rlp:"-"`
+}
+
+var (
+ BTCAddress = common.HexToAddress("0xC2fa1BA90b15E3612E0067A0020192938784D9C5")
+ ETHAddress = common.HexToAddress("0xAad540ac542C3688652a3fc7b8e21B3fC1D097e9")
+ XRPAddress = common.HexToAddress("0x5dc27D59bB80E0EF853Bb2e27B94113DF08F547F")
+ LTCAddress = common.HexToAddress("0x6F98655A8fa7AEEF3147ee002c666d09c7AA4F5c")
+ BNBAddress = common.HexToAddress("0xaC389aCA56394a5B14918cF6437600760B6c650C")
+ ADAAddress = common.HexToAddress("0x576201Ac3f1E0fe483a9320DaCc4B08EB3E58306")
+ ETCAddress = common.HexToAddress("0xf992cf45394dAc5f50A26446de17803a79B940da")
+ BCHAddress = common.HexToAddress("0xFDF68dE6dFFd893221fc9f7985FeBC2AB20761A6")
+ EOSAddress = common.HexToAddress("0xd9bb01454c85247B2ef35BB5BE57384cC275a8cf")
+ USDAddress = common.HexToAddress("0x45c25041b8e6CBD5c963E7943007187C3673C7c9")
+ _1E18 = new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(100))
+ _1E17 = new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(10))
+ _1E8 = big.NewInt(100000000)
+ _1E7 = big.NewInt(10000000)
+)
+
+func getNonce(t *testing.T, userAddress common.Address) (uint64, error) {
+ rpcClient, err := rpc.DialHTTP("http://127.0.0.1:8501")
+ defer rpcClient.Close()
+ if err != nil {
+ return 0, err
+ }
+ var result interface{}
+ if err != nil {
+
+ return 0, err
+ }
+ err = rpcClient.Call(&result, "XDCx_getOrderCount", userAddress)
+ if err != nil {
+ return 0, err
+ }
+ s := result.(string)
+ s = strings.TrimPrefix(s, "0x")
+ n, err := strconv.ParseUint(s, 16, 32)
+ return uint64(n), nil
+}
+func testSendOrder(t *testing.T, amount, price *big.Int, side string, status string, orderID uint64) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA("65ec4d4dfbcac594a14c36baa462d6f73cd86134840f6cf7b80a1e1cd33473e2")
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &OrderMsg{
+ Quantity: amount,
+ Price: price,
+ ExchangeAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ BaseToken: common.HexToAddress(common.XDCNativeAddress),
+ QuoteToken: BTCAddress,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ }
+ nonce, _ := getNonce(t, msg.UserAddress)
+ tx := types.NewOrderTransaction(nonce, msg.Quantity, msg.Price, msg.ExchangeAddress, msg.UserAddress, msg.BaseToken, msg.QuoteToken, msg.Status, msg.Side, msg.Type, common.Hash{}, orderID)
+ signedTx, err := types.OrderSignTx(tx, types.OrderTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+
+ err = client.SendOrderTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func testSendOrderXDCUSD(t *testing.T, amount, price *big.Int, side string, status string, orderID uint64) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA("65ec4d4dfbcac594a14c36baa462d6f73cd86134840f6cf7b80a1e1cd33473e2")
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &OrderMsg{
+ Quantity: amount,
+ Price: price,
+ ExchangeAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ BaseToken: common.HexToAddress(common.XDCNativeAddress),
+ QuoteToken: USDAddress,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ }
+ nonce, _ := getNonce(t, msg.UserAddress)
+ tx := types.NewOrderTransaction(nonce, msg.Quantity, msg.Price, msg.ExchangeAddress, msg.UserAddress, msg.BaseToken, msg.QuoteToken, msg.Status, msg.Side, msg.Type, common.Hash{}, orderID)
+ signedTx, err := types.OrderSignTx(tx, types.OrderTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+
+ err = client.SendOrderTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func testSendOrderBTCUSD(t *testing.T, amount, price *big.Int, side string, status string, orderID uint64) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA("65ec4d4dfbcac594a14c36baa462d6f73cd86134840f6cf7b80a1e1cd33473e2")
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &OrderMsg{
+ Quantity: amount,
+ Price: price,
+ ExchangeAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ BaseToken: BTCAddress,
+ QuoteToken: USDAddress,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ }
+ nonce, _ := getNonce(t, msg.UserAddress)
+ tx := types.NewOrderTransaction(nonce, msg.Quantity, msg.Price, msg.ExchangeAddress, msg.UserAddress, msg.BaseToken, msg.QuoteToken, msg.Status, msg.Side, msg.Type, common.Hash{}, orderID)
+ signedTx, err := types.OrderSignTx(tx, types.OrderTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+
+ err = client.SendOrderTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func testSendOrderXDCBTC(t *testing.T, amount, price *big.Int, side string, status string, orderID uint64) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA("65ec4d4dfbcac594a14c36baa462d6f73cd86134840f6cf7b80a1e1cd33473e2")
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &OrderMsg{
+ Quantity: amount,
+ Price: price,
+ ExchangeAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ BaseToken: common.HexToAddress(common.XDCNativeAddress),
+ QuoteToken: BTCAddress,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ }
+ nonce, _ := getNonce(t, msg.UserAddress)
+ tx := types.NewOrderTransaction(nonce, msg.Quantity, msg.Price, msg.ExchangeAddress, msg.UserAddress, msg.BaseToken, msg.QuoteToken, msg.Status, msg.Side, msg.Type, common.Hash{}, orderID)
+ signedTx, err := types.OrderSignTx(tx, types.OrderTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+
+ err = client.SendOrderTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func testSendOrderETHBTC(t *testing.T, amount, price *big.Int, side string, status string, orderID uint64) {
+
+ client, err := ethclient.Dial("http://127.0.0.1:8501")
+ if err != nil {
+ log.Print(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA("65ec4d4dfbcac594a14c36baa462d6f73cd86134840f6cf7b80a1e1cd33473e2")
+ if err != nil {
+ log.Print(err)
+ }
+ msg := &OrderMsg{
+ Quantity: amount,
+ Price: price,
+ ExchangeAddress: common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"),
+ UserAddress: crypto.PubkeyToAddress(privateKey.PublicKey),
+ BaseToken: ETHAddress,
+ QuoteToken: BTCAddress,
+ Status: status,
+ Side: side,
+ Type: "LO",
+ }
+ nonce, _ := getNonce(t, msg.UserAddress)
+ tx := types.NewOrderTransaction(nonce, msg.Quantity, msg.Price, msg.ExchangeAddress, msg.UserAddress, msg.BaseToken, msg.QuoteToken, msg.Status, msg.Side, msg.Type, common.Hash{}, orderID)
+ signedTx, err := types.OrderSignTx(tx, types.OrderTxSigner{}, privateKey)
+ if err != nil {
+ log.Print(err)
+ }
+
+ err = client.SendOrderTransaction(context.Background(), signedTx)
+ if err != nil {
+ log.Print(err)
+ }
+}
+
+func TestSendBuyOrder(t *testing.T) {
+ testSendOrder(t, new(big.Int).SetUint64(1000000000000000000), new(big.Int).SetUint64(100000000000000000), "BUY", "NEW", 0)
+}
+
+func TestSendSellOrder(t *testing.T) {
+ testSendOrder(t, new(big.Int).SetUint64(1000000000000000000), new(big.Int).SetUint64(100000000000000000), "SELL", "NEW", 0)
+}
+func TestFilled(t *testing.T) {
+ ////BTC/XDC
+ //BTCUSDPrice := new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(5000))
+ //testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(5000)), BTCUSDPrice, "BUY", "NEW", 0)
+ //ETH/BTC
+
+ BTCUSDPrice := new(big.Int).Mul(_1E8, big.NewInt(10000)) // 10000
+ time.Sleep(2 * time.Second)
+ testSendOrderBTCUSD(t, _1E18, BTCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderBTCUSD(t, _1E18, BTCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderBTCUSD(t, new(big.Int).Mul(big.NewInt(2), _1E18), BTCUSDPrice, "SELL", "NEW", 0)
+
+ XDCBTCPrice := new(big.Int).Mul(big.NewInt(10000000000000), big.NewInt(6)) // 0.00006
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCBTC(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCBTCPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCBTC(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCBTCPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCBTC(t, new(big.Int).Mul(big.NewInt(1200000), _1E18), XDCBTCPrice, "SELL", "NEW", 0)
+
+ XDCUSDPrice := new(big.Int).Mul(_1E7, big.NewInt(6)) // 0.6
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(1200000), _1E18), XDCUSDPrice, "SELL", "NEW", 0)
+
+}
+
+func TestX10Filled(t *testing.T) {
+ XDCUSDPrice := new(big.Int).Mul(_1E7, big.NewInt(60)) // 6
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCUSDPrice, "BUY", "NEW", 0)
+ time.Sleep(2 * time.Second)
+ testSendOrderXDCUSD(t, new(big.Int).Mul(big.NewInt(1200000), _1E18), XDCUSDPrice, "SELL", "NEW", 0)
+
+}
+func TestPartialFilled(t *testing.T) {
+
+}
+func TestNoMatch(t *testing.T) {
+
+}
+
+func TestCancelOrder(t *testing.T) {
+ XDCBTCPrice := new(big.Int).Mul(big.NewInt(10000000000000), big.NewInt(6)) // 0.00006
+ testSendOrder(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCBTCPrice, "BUY", "NEW", 0)
+ time.Sleep(5 * time.Second)
+ testSendOrder(t, new(big.Int).Mul(big.NewInt(600000), _1E18), XDCBTCPrice, "BUY", "CANCELLED", 3)
+ time.Sleep(5 * time.Second)
+ //testSendOrder(t, new(big.Int).SetUint64(48), new(big.Int).SetUint64(15), "SELL", "NEW", 0)
+}
diff --git a/core/order_tx_journal.go b/core/order_tx_journal.go
new file mode 100644
index 0000000000..471c2f34f9
--- /dev/null
+++ b/core/order_tx_journal.go
@@ -0,0 +1,149 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "io"
+ "os"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+)
+
+// ordertxJournal is a rotating log of transactions with the aim of storing locally
+// created transactions to allow non-executed ones to survive node restarts.
+type ordertxJournal struct {
+ path string // Filesystem path to store the transactions at
+ writer io.WriteCloser // Output stream to write new transactions into
+}
+
+// newOrderTxJournal creates a new transaction journal to
+func newOrderTxJournal(path string) *ordertxJournal {
+ return &ordertxJournal{
+ path: path,
+ }
+}
+
+// load parses a transaction journal dump from disk, loading its contents into
+// the specified pool.
+func (journal *ordertxJournal) load(add func(*types.OrderTransaction) error) error {
+ // Skip the parsing if the journal file doens't exist at all
+ if _, err := os.Stat(journal.path); os.IsNotExist(err) {
+ return nil
+ }
+ // Open the journal for loading any past transactions
+ input, err := os.Open(journal.path)
+ if err != nil {
+ return err
+ }
+ defer input.Close()
+
+ // Temporarily discard any journal additions (don't double add on load)
+ journal.writer = new(devNull)
+ defer func() { journal.writer = nil }()
+
+ // Inject all transactions from the journal into the pool
+ stream := rlp.NewStream(input, 0)
+ total, dropped := 0, 0
+
+ var failure error
+ for {
+ // Parse the next transaction and terminate on error
+ tx := new(types.OrderTransaction)
+ if err = stream.Decode(tx); err != nil {
+ if err != io.EOF {
+ failure = err
+ }
+ break
+ }
+ // Import the transaction and bump the appropriate progress counters
+ total++
+ if err = add(tx); err != nil {
+ log.Debug("Failed to add journaled transaction", "err", err)
+ dropped++
+ continue
+ }
+ }
+ log.Info("Loaded local transaction journal", "transactions", total, "dropped", dropped)
+
+ return failure
+}
+
+// insert adds the specified transaction to the local disk journal.
+func (journal *ordertxJournal) insert(tx *types.OrderTransaction) error {
+ if journal.writer == nil {
+ return errNoActiveJournal
+ }
+ if err := rlp.Encode(journal.writer, tx); err != nil {
+ return err
+ }
+ return nil
+}
+
+// rotate regenerates the transaction journal based on the current contents of
+// the transaction pool.
+func (journal *ordertxJournal) rotate(all map[common.Address]types.OrderTransactions) error {
+ // Close the current journal (if any is open)
+ if journal.writer != nil {
+ if err := journal.writer.Close(); err != nil {
+ return err
+ }
+ journal.writer = nil
+ }
+ // Generate a new journal with the contents of the current pool
+ replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
+ if err != nil {
+ return err
+ }
+ journaled := 0
+ for _, txs := range all {
+ for _, tx := range txs {
+ if err = rlp.Encode(replacement, tx); err != nil {
+ replacement.Close()
+ return err
+ }
+ }
+ journaled += len(txs)
+ }
+ replacement.Close()
+
+ // Replace the live journal with the newly generated one
+ if err = os.Rename(journal.path+".new", journal.path); err != nil {
+ return err
+ }
+ sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0755)
+ if err != nil {
+ return err
+ }
+ journal.writer = sink
+ log.Info("Regenerated local transaction journal", "transactions", journaled, "accounts", len(all))
+
+ return nil
+}
+
+// close flushes the transaction journal contents to disk and closes the file.
+func (journal *ordertxJournal) close() error {
+ var err error
+
+ if journal.writer != nil {
+ err = journal.writer.Close()
+ journal.writer = nil
+ }
+ return err
+}
diff --git a/core/order_tx_list.go b/core/order_tx_list.go
new file mode 100644
index 0000000000..5135bfe4fd
--- /dev/null
+++ b/core/order_tx_list.go
@@ -0,0 +1,289 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package core
+
+import (
+ "container/heap"
+ "sort"
+
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+)
+
+// txSortedMap is a nonce->transaction hash map with a heap based index to allow
+// iterating over the contents in a nonce-incrementing way.
+type ordertxSortedMap struct {
+ items map[uint64]*types.OrderTransaction // Hash map storing the transaction data
+ index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
+ cache types.OrderTransactions // Cache of the transactions already sorted
+}
+
+// newTxSortedMap creates a new nonce-sorted transaction map.
+func newOrderTxSortedMap() *ordertxSortedMap {
+ return &ordertxSortedMap{
+ items: make(map[uint64]*types.OrderTransaction),
+ index: new(nonceHeap),
+ }
+}
+
+// Get retrieves the current transactions associated with the given nonce.
+func (m *ordertxSortedMap) Get(nonce uint64) *types.OrderTransaction {
+ return m.items[nonce]
+}
+
+// Put inserts a new transaction into the map, also updating the map's nonce
+// index. If a transaction already exists with the same nonce, it's overwritten.
+func (m *ordertxSortedMap) Put(tx *types.OrderTransaction) {
+ nonce := tx.Nonce()
+ if m.items[nonce] == nil {
+ heap.Push(m.index, nonce)
+ }
+ m.items[nonce], m.cache = tx, nil
+}
+
+// Forward removes all transactions from the map with a nonce lower than the
+// provided threshold. Every removed transaction is returned for any post-removal
+// maintenance.
+func (m *ordertxSortedMap) Forward(threshold uint64) types.OrderTransactions {
+ var removed types.OrderTransactions
+
+ // Pop off heap items until the threshold is reached
+ for m.index.Len() > 0 && (*m.index)[0] < threshold {
+ nonce := heap.Pop(m.index).(uint64)
+ removed = append(removed, m.items[nonce])
+ delete(m.items, nonce)
+ }
+ // If we had a cached order, shift the front
+ if m.cache != nil {
+ m.cache = m.cache[len(removed):]
+ }
+ return removed
+}
+
+// Filter iterates over the list of transactions and removes all of them for which
+// the specified function evaluates to true.
+func (m *ordertxSortedMap) Filter(filter func(*types.OrderTransaction) bool) types.OrderTransactions {
+ var removed types.OrderTransactions
+
+ // Collect all the transactions to filter out
+ for nonce, tx := range m.items {
+ if filter(tx) {
+ removed = append(removed, tx)
+ delete(m.items, nonce)
+ }
+ }
+ // If transactions were removed, the heap and cache are ruined
+ if len(removed) > 0 {
+ *m.index = make([]uint64, 0, len(m.items))
+ for nonce := range m.items {
+ *m.index = append(*m.index, nonce)
+ }
+ heap.Init(m.index)
+
+ m.cache = nil
+ }
+ return removed
+}
+
+// Cap places a hard limit on the number of items, returning all transactions
+// exceeding that limit.
+func (m *ordertxSortedMap) Cap(threshold int) types.OrderTransactions {
+ // Short circuit if the number of items is under the limit
+ if len(m.items) <= threshold {
+ return nil
+ }
+ // Otherwise gather and drop the highest nonce'd transactions
+ var drops types.OrderTransactions
+
+ sort.Sort(*m.index)
+ for size := len(m.items); size > threshold; size-- {
+ drops = append(drops, m.items[(*m.index)[size-1]])
+ delete(m.items, (*m.index)[size-1])
+ }
+ *m.index = (*m.index)[:threshold]
+ heap.Init(m.index)
+
+ // If we had a cache, shift the back
+ if m.cache != nil {
+ m.cache = m.cache[:len(m.cache)-len(drops)]
+ }
+ return drops
+}
+
+// Remove deletes a transaction from the maintained map, returning whether the
+// transaction was found.
+func (m *ordertxSortedMap) Remove(nonce uint64) bool {
+ // Short circuit if no transaction is present
+ _, ok := m.items[nonce]
+ if !ok {
+ return false
+ }
+ // Otherwise delete the transaction and fix the heap index
+ for i := 0; i < m.index.Len(); i++ {
+ if (*m.index)[i] == nonce {
+ heap.Remove(m.index, i)
+ break
+ }
+ }
+ delete(m.items, nonce)
+ m.cache = nil
+
+ return true
+}
+
+// Ready retrieves a sequentially increasing list of transactions starting at the
+// provided nonce that is ready for processing. The returned transactions will be
+// removed from the list.
+//
+// Note, all transactions with nonces lower than start will also be returned to
+// prevent getting into and invalid state. This is not something that should ever
+// happen but better to be self correcting than failing!
+func (m *ordertxSortedMap) Ready(start uint64) types.OrderTransactions {
+ // Short circuit if no transactions are available
+ if m.index.Len() == 0 || (*m.index)[0] > start {
+ return nil
+ }
+ // Otherwise start accumulating incremental transactions
+ var ready types.OrderTransactions
+ for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
+ ready = append(ready, m.items[next])
+ delete(m.items, next)
+ heap.Pop(m.index)
+ }
+ m.cache = nil
+
+ return ready
+}
+
+// Len returns the length of the transaction map.
+func (m *ordertxSortedMap) Len() int {
+ return len(m.items)
+}
+
+// Flatten creates a nonce-sorted slice of transactions based on the loosely
+// sorted internal representation. The result of the sorting is cached in case
+// it's requested again before any modifications are made to the contents.
+func (m *ordertxSortedMap) Flatten() types.OrderTransactions {
+ // If the sorting was not cached yet, create and cache it
+ if m.cache == nil {
+ m.cache = make(types.OrderTransactions, 0, len(m.items))
+ for _, tx := range m.items {
+ m.cache = append(m.cache, tx)
+ }
+ sort.Sort(types.OrderTxByNonce(m.cache))
+ }
+ // Copy the cache to prevent accidental modifications
+ txs := make(types.OrderTransactions, len(m.cache))
+ copy(txs, m.cache)
+ return txs
+}
+
+// txList is a "list" of transactions belonging to an account, sorted by account
+// nonce. The same type can be used both for storing contiguous transactions for
+// the executable/pending queue; and for storing gapped transactions for the non-
+// executable/future queue, with minor behavioral changes.
+type ordertxList struct {
+ strict bool // Whether nonces are strictly continuous or not
+ txs *ordertxSortedMap // Heap indexed sorted hash map of the transactions
+}
+
+// newTxList create a new transaction list for maintaining nonce-indexable fast,
+// gapped, sortable transaction lists.
+func newOrderTxList(strict bool) *ordertxList {
+ return &ordertxList{
+ strict: strict,
+ txs: newOrderTxSortedMap(),
+ }
+}
+
+// Overlaps returns whether the transaction specified has the same nonce as one
+// already contained within the list.
+func (l *ordertxList) Overlaps(tx *types.OrderTransaction) bool {
+ return l.txs.Get(tx.Nonce()) != nil
+}
+
+// Add tries to insert a new transaction into the list, returning whether the
+// transaction was accepted, and if yes, any previous transaction it replaced.
+//
+// If the new transaction is accepted into the list, the lists' cost and gas
+// thresholds are also potentially updated.
+func (l *ordertxList) Add(tx *types.OrderTransaction) (bool, *types.OrderTransaction) {
+ // If there's an older better transaction, abort
+ old := l.txs.Get(tx.Nonce())
+ if old != nil {
+ l.txs.Put(tx)
+ return true, old
+ }
+ l.txs.Put(tx)
+ return true, nil
+}
+
+// Forward removes all transactions from the list with a nonce lower than the
+// provided threshold. Every removed transaction is returned for any post-removal
+// maintenance.
+func (l *ordertxList) Forward(threshold uint64) types.OrderTransactions {
+ return l.txs.Forward(threshold)
+}
+
+// Cap places a hard limit on the number of items, returning all transactions
+// exceeding that limit.
+func (l *ordertxList) Cap(threshold int) types.OrderTransactions {
+ return l.txs.Cap(threshold)
+}
+
+// Remove deletes a transaction from the maintained list, returning whether the
+// transaction was found, and also returning any transaction invalidated due to
+// the deletion (strict mode only).
+func (l *ordertxList) Remove(tx *types.OrderTransaction) (bool, types.OrderTransactions) {
+ // Remove the transaction from the set
+ nonce := tx.Nonce()
+ if removed := l.txs.Remove(nonce); !removed {
+ return false, nil
+ }
+ // In strict mode, filter out non-executable transactions
+ if l.strict {
+ return true, l.txs.Filter(func(tx *types.OrderTransaction) bool { return tx.Nonce() > nonce })
+ }
+ return true, nil
+}
+
+// Ready retrieves a sequentially increasing list of transactions starting at the
+// provided nonce that is ready for processing. The returned transactions will be
+// removed from the list.
+//
+// Note, all transactions with nonces lower than start will also be returned to
+// prevent getting into and invalid state. This is not something that should ever
+// happen but better to be self correcting than failing!
+func (l *ordertxList) Ready(start uint64) types.OrderTransactions {
+ return l.txs.Ready(start)
+}
+
+// Len returns the length of the transaction list.
+func (l *ordertxList) Len() int {
+ return l.txs.Len()
+}
+
+// Empty returns whether the list of transactions is empty or not.
+func (l *ordertxList) Empty() bool {
+ return l.Len() == 0
+}
+
+// Flatten creates a nonce-sorted slice of transactions based on the loosely
+// sorted internal representation. The result of the sorting is cached in case
+// it's requested again before any modifications are made to the contents.
+func (l *ordertxList) Flatten() types.OrderTransactions {
+ return l.txs.Flatten()
+}
diff --git a/core/rawdb/database.go b/core/rawdb/database.go
new file mode 100644
index 0000000000..7142d3048f
--- /dev/null
+++ b/core/rawdb/database.go
@@ -0,0 +1,110 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/ethdb/leveldb"
+ "github.com/XinFinOrg/XDPoSChain/ethdb/memorydb"
+)
+
+// freezerdb is a database wrapper that enabled freezer data retrievals.
+type freezerdb struct {
+ ethdb.KeyValueStore
+ ethdb.AncientStore
+}
+
+// Close implements io.Closer, closing both the fast key-value store as well as
+// the slow ancient tables.
+func (frdb *freezerdb) Close() error {
+ var errs []error
+ if err := frdb.AncientStore.Close(); err != nil {
+ errs = append(errs, err)
+ }
+ if err := frdb.KeyValueStore.Close(); err != nil {
+ errs = append(errs, err)
+ }
+ if len(errs) != 0 {
+ return fmt.Errorf("%v", errs)
+ }
+ return nil
+}
+
+// nofreezedb is a database wrapper that disables freezer data retrievals.
+type nofreezedb struct {
+ ethdb.KeyValueStore
+}
+
+// HasAncient returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) HasAncient(kind string, number uint64) (bool, error) {
+ return false, errNotSupported
+}
+
+// Ancient returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) {
+ return nil, errNotSupported
+}
+
+// Ancients returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) Ancients() (uint64, error) {
+ return 0, errNotSupported
+}
+
+// AncientSize returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) AncientSize(kind string) (uint64, error) {
+ return 0, errNotSupported
+}
+
+// AppendAncient returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error {
+ return errNotSupported
+}
+
+// TruncateAncients returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) TruncateAncients(items uint64) error {
+ return errNotSupported
+}
+
+// Sync returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) Sync() error {
+ return errNotSupported
+}
+
+// NewDatabase creates a high level database on top of a given key-value data
+// store without a freezer moving immutable chain segments into cold storage.
+func NewDatabase(db ethdb.KeyValueStore) ethdb.Database {
+ return &nofreezedb{
+ KeyValueStore: db,
+ }
+}
+
+// NewMemoryDatabase creates an ephemeral in-memory key-value database without a
+// freezer moving immutable chain segments into cold storage.
+func NewMemoryDatabase() ethdb.Database {
+ return NewDatabase(memorydb.New())
+}
+
+// NewLevelDBDatabase creates a persistent key-value database without a freezer
+// moving immutable chain segments into cold storage.
+func NewLevelDBDatabase(file string, cache int, handles int, namespace string) (ethdb.Database, error) {
+ db, err := leveldb.New(file, cache, handles, namespace)
+ if err != nil {
+ return nil, err
+ }
+ return NewDatabase(db), nil
+}
diff --git a/dashboard/assets/index.jsx b/core/rawdb/freezer_table.go
similarity index 56%
rename from dashboard/assets/index.jsx
rename to core/rawdb/freezer_table.go
index 4ee567b01b..fa174acd65 100644
--- a/dashboard/assets/index.jsx
+++ b/core/rawdb/freezer_table.go
@@ -1,6 +1,4 @@
-// @flow
-
-// Copyright 2017 The go-ethereum Authors
+// Copyright 2019 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -16,26 +14,21 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-import React from 'react';
-import {render} from 'react-dom';
+package rawdb
-import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
-import createMuiTheme from 'material-ui/styles/createMuiTheme';
+import (
+ "errors"
+)
-import Dashboard from './components/Dashboard';
+var (
+ // errClosed is returned if an operation attempts to read from or write to the
+ // freezer table after it has already been closed.
+ errClosed = errors.New("closed")
-const theme: Object = createMuiTheme({
- palette: {
- type: 'dark',
- },
-});
-const dashboard = document.getElementById('dashboard');
-if (dashboard) {
- // Renders the whole dashboard.
- render(
-
-
- ,
- dashboard,
- );
-}
+ // errOutOfBounds is returned if the item requested is not contained within the
+ // freezer table.
+ errOutOfBounds = errors.New("out of bounds")
+
+ // errNotSupported is returned if the database doesn't support the required operation.
+ errNotSupported = errors.New("this operation is not supported")
+)
diff --git a/core/rawdb/table.go b/core/rawdb/table.go
new file mode 100644
index 0000000000..dfb58c07b6
--- /dev/null
+++ b/core/rawdb/table.go
@@ -0,0 +1,259 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+)
+
+// table is a wrapper around a database that prefixes each key access with a pre-
+// configured string.
+type table struct {
+ db ethdb.Database
+ prefix string
+}
+
+// NewTable returns a database object that prefixes all keys with a given string.
+func NewTable(db ethdb.Database, prefix string) ethdb.Database {
+ return &table{
+ db: db,
+ prefix: prefix,
+ }
+}
+
+// Close is a noop to implement the Database interface.
+func (t *table) Close() error {
+ return nil
+}
+
+// Has retrieves if a prefixed version of a key is present in the database.
+func (t *table) Has(key []byte) (bool, error) {
+ return t.db.Has(append([]byte(t.prefix), key...))
+}
+
+// Get retrieves the given prefixed key if it's present in the database.
+func (t *table) Get(key []byte) ([]byte, error) {
+ return t.db.Get(append([]byte(t.prefix), key...))
+}
+
+// HasAncient is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) HasAncient(kind string, number uint64) (bool, error) {
+ return t.db.HasAncient(kind, number)
+}
+
+// Ancient is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) Ancient(kind string, number uint64) ([]byte, error) {
+ return t.db.Ancient(kind, number)
+}
+
+// Ancients is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) Ancients() (uint64, error) {
+ return t.db.Ancients()
+}
+
+// AncientSize is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) AncientSize(kind string) (uint64, error) {
+ return t.db.AncientSize(kind)
+}
+
+// AppendAncient is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error {
+ return t.db.AppendAncient(number, hash, header, body, receipts, td)
+}
+
+// TruncateAncients is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) TruncateAncients(items uint64) error {
+ return t.db.TruncateAncients(items)
+}
+
+// Sync is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) Sync() error {
+ return t.db.Sync()
+}
+
+// Put inserts the given value into the database at a prefixed version of the
+// provided key.
+func (t *table) Put(key []byte, value []byte) error {
+ return t.db.Put(append([]byte(t.prefix), key...), value)
+}
+
+// Delete removes the given prefixed key from the database.
+func (t *table) Delete(key []byte) error {
+ return t.db.Delete(append([]byte(t.prefix), key...))
+}
+
+// NewIterator creates a binary-alphabetical iterator over a subset
+// of database content with a particular key prefix, starting at a particular
+// initial key (or after, if it does not exist).
+func (t *table) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
+ innerPrefix := append([]byte(t.prefix), prefix...)
+ iter := t.db.NewIterator(innerPrefix, start)
+ return &tableIterator{
+ iter: iter,
+ prefix: t.prefix,
+ }
+}
+
+// Stat returns a particular internal stat of the database.
+func (t *table) Stat(property string) (string, error) {
+ return t.db.Stat(property)
+}
+
+// Compact flattens the underlying data store for the given key range. In essence,
+// deleted and overwritten versions are discarded, and the data is rearranged to
+// reduce the cost of operations needed to access them.
+//
+// A nil start is treated as a key before all keys in the data store; a nil limit
+// is treated as a key after all keys in the data store. If both is nil then it
+// will compact entire data store.
+func (t *table) Compact(start []byte, limit []byte) error {
+ // If no start was specified, use the table prefix as the first value
+ if start == nil {
+ start = []byte(t.prefix)
+ }
+ // If no limit was specified, use the first element not matching the prefix
+ // as the limit
+ if limit == nil {
+ limit = []byte(t.prefix)
+ for i := len(limit) - 1; i >= 0; i-- {
+ // Bump the current character, stopping if it doesn't overflow
+ limit[i]++
+ if limit[i] > 0 {
+ break
+ }
+ // Character overflown, proceed to the next or nil if the last
+ if i == 0 {
+ limit = nil
+ }
+ }
+ }
+ // Range correctly calculated based on table prefix, delegate down
+ return t.db.Compact(start, limit)
+}
+
+// NewBatch creates a write-only database that buffers changes to its host db
+// until a final write is called, each operation prefixing all keys with the
+// pre-configured string.
+func (t *table) NewBatch() ethdb.Batch {
+ return &tableBatch{t.db.NewBatch(), t.prefix}
+}
+
+// tableBatch is a wrapper around a database batch that prefixes each key access
+// with a pre-configured string.
+type tableBatch struct {
+ batch ethdb.Batch
+ prefix string
+}
+
+// Put inserts the given value into the batch for later committing.
+func (b *tableBatch) Put(key, value []byte) error {
+ return b.batch.Put(append([]byte(b.prefix), key...), value)
+}
+
+// Delete inserts the a key removal into the batch for later committing.
+func (b *tableBatch) Delete(key []byte) error {
+ return b.batch.Delete(append([]byte(b.prefix), key...))
+}
+
+// ValueSize retrieves the amount of data queued up for writing.
+func (b *tableBatch) ValueSize() int {
+ return b.batch.ValueSize()
+}
+
+// Write flushes any accumulated data to disk.
+func (b *tableBatch) Write() error {
+ return b.batch.Write()
+}
+
+// Reset resets the batch for reuse.
+func (b *tableBatch) Reset() {
+ b.batch.Reset()
+}
+
+// tableReplayer is a wrapper around a batch replayer which truncates
+// the added prefix.
+type tableReplayer struct {
+ w ethdb.KeyValueWriter
+ prefix string
+}
+
+// Put implements the interface KeyValueWriter.
+func (r *tableReplayer) Put(key []byte, value []byte) error {
+ trimmed := key[len(r.prefix):]
+ return r.w.Put(trimmed, value)
+}
+
+// Delete implements the interface KeyValueWriter.
+func (r *tableReplayer) Delete(key []byte) error {
+ trimmed := key[len(r.prefix):]
+ return r.w.Delete(trimmed)
+}
+
+// Replay replays the batch contents.
+func (b *tableBatch) Replay(w ethdb.KeyValueWriter) error {
+ return b.batch.Replay(&tableReplayer{w: w, prefix: b.prefix})
+}
+
+// tableIterator is a wrapper around a database iterator that prefixes each key access
+// with a pre-configured string.
+type tableIterator struct {
+ iter ethdb.Iterator
+ prefix string
+}
+
+// Next moves the iterator to the next key/value pair. It returns whether the
+// iterator is exhausted.
+func (iter *tableIterator) Next() bool {
+ return iter.iter.Next()
+}
+
+// Error returns any accumulated error. Exhausting all the key/value pairs
+// is not considered to be an error.
+func (iter *tableIterator) Error() error {
+ return iter.iter.Error()
+}
+
+// Key returns the key of the current key/value pair, or nil if done. The caller
+// should not modify the contents of the returned slice, and its contents may
+// change on the next call to Next.
+func (iter *tableIterator) Key() []byte {
+ key := iter.iter.Key()
+ if key == nil {
+ return nil
+ }
+ return key[len(iter.prefix):]
+}
+
+// Value returns the value of the current key/value pair, or nil if done. The
+// caller should not modify the contents of the returned slice, and its contents
+// may change on the next call to Next.
+func (iter *tableIterator) Value() []byte {
+ return iter.iter.Value()
+}
+
+// Release releases associated resources. Release should always succeed and can
+// be called multiple times without causing error.
+func (iter *tableIterator) Release() {
+ iter.iter.Release()
+}
diff --git a/core/rawdb/table_test.go b/core/rawdb/table_test.go
new file mode 100644
index 0000000000..2255271865
--- /dev/null
+++ b/core/rawdb/table_test.go
@@ -0,0 +1,128 @@
+// Copyright 2020 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+)
+
+func TestTableDatabase(t *testing.T) { testTableDatabase(t, "prefix") }
+func TestEmptyPrefixTableDatabase(t *testing.T) { testTableDatabase(t, "") }
+
+type testReplayer struct {
+ puts [][]byte
+ dels [][]byte
+}
+
+func (r *testReplayer) Put(key []byte, value []byte) error {
+ r.puts = append(r.puts, key)
+ return nil
+}
+
+func (r *testReplayer) Delete(key []byte) error {
+ r.dels = append(r.dels, key)
+ return nil
+}
+
+func testTableDatabase(t *testing.T, prefix string) {
+ db := NewTable(NewMemoryDatabase(), prefix)
+
+ var entries = []struct {
+ key []byte
+ value []byte
+ }{
+ {[]byte{0x01, 0x02}, []byte{0x0a, 0x0b}},
+ {[]byte{0x03, 0x04}, []byte{0x0c, 0x0d}},
+ {[]byte{0x05, 0x06}, []byte{0x0e, 0x0f}},
+
+ {[]byte{0xff, 0xff, 0x01}, []byte{0x1a, 0x1b}},
+ {[]byte{0xff, 0xff, 0x02}, []byte{0x1c, 0x1d}},
+ {[]byte{0xff, 0xff, 0x03}, []byte{0x1e, 0x1f}},
+ }
+
+ // Test Put/Get operation
+ for _, entry := range entries {
+ db.Put(entry.key, entry.value)
+ }
+ for _, entry := range entries {
+ got, err := db.Get(entry.key)
+ if err != nil {
+ t.Fatalf("Failed to get value: %v", err)
+ }
+ if !bytes.Equal(got, entry.value) {
+ t.Fatalf("Value mismatch: want=%v, got=%v", entry.value, got)
+ }
+ }
+
+ // Test batch operation
+ db = NewTable(NewMemoryDatabase(), prefix)
+ batch := db.NewBatch()
+ for _, entry := range entries {
+ batch.Put(entry.key, entry.value)
+ }
+ batch.Write()
+ for _, entry := range entries {
+ got, err := db.Get(entry.key)
+ if err != nil {
+ t.Fatalf("Failed to get value: %v", err)
+ }
+ if !bytes.Equal(got, entry.value) {
+ t.Fatalf("Value mismatch: want=%v, got=%v", entry.value, got)
+ }
+ }
+
+ // Test batch replayer
+ r := &testReplayer{}
+ batch.Replay(r)
+ for index, entry := range entries {
+ got := r.puts[index]
+ if !bytes.Equal(got, entry.key) {
+ t.Fatalf("Key mismatch: want=%v, got=%v", entry.key, got)
+ }
+ }
+
+ check := func(iter ethdb.Iterator, expCount, index int) {
+ count := 0
+ for iter.Next() {
+ key, value := iter.Key(), iter.Value()
+ if !bytes.Equal(key, entries[index].key) {
+ t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key)
+ }
+ if !bytes.Equal(value, entries[index].value) {
+ t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value)
+ }
+ index += 1
+ count++
+ }
+ if count != expCount {
+ t.Fatalf("Wrong number of elems, exp %d got %d", expCount, count)
+ }
+ iter.Release()
+ }
+ // Test iterators
+ check(db.NewIterator(nil, nil), 6, 0)
+ // Test iterators with prefix
+ check(db.NewIterator([]byte{0xff, 0xff}, nil), 3, 3)
+ // Test iterators with start point
+ check(db.NewIterator(nil, []byte{0xff, 0xff, 0x02}), 2, 4)
+ // Test iterators with prefix and start point
+ check(db.NewIterator([]byte{0xee}, nil), 0, 0)
+ check(db.NewIterator(nil, []byte{0x00}), 6, 0)
+}
diff --git a/core/state/database.go b/core/state/database.go
index 36926ec69d..03e4a67ac3 100644
--- a/core/state/database.go
+++ b/core/state/database.go
@@ -18,22 +18,14 @@ package state
import (
"fmt"
- "sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/trie"
lru "github.com/hashicorp/golang-lru"
)
-// Trie cache generation limit after which to evic trie nodes from memory.
-var MaxTrieCacheGen = uint16(120)
-
const (
- // Number of past tries to keep. This value is chosen such that
- // reasonable chain reorg depths will hit an existing trie.
- maxPastTries = 12
-
// Number of codehash->size associations to keep.
codeSizeCacheSize = 100000
)
@@ -59,76 +51,87 @@ type Database interface {
TrieDB() *trie.Database
}
-// Trie is a Ethereum Merkle Trie.
+// Trie is a Ethereum Merkle Patricia trie.
type Trie interface {
+ // GetKey returns the sha3 preimage of a hashed key that was previously used
+ // to store a value.
+ //
+ // TODO(fjl): remove this when SecureTrie is removed
+ GetKey([]byte) []byte
+
+ // TryGet returns the value for key stored in the trie. The value bytes must
+ // not be modified by the caller. If a node was not found in the database, a
+ // trie.MissingNodeError is returned.
TryGet(key []byte) ([]byte, error)
+
+ // TryUpdate associates key with value in the trie. If value has length zero, any
+ // existing value is deleted from the trie. The value bytes must not be modified
+ // by the caller while they are stored in the trie. If a node was not found in the
+ // database, a trie.MissingNodeError is returned.
TryUpdate(key, value []byte) error
+
+ // TryDelete removes any existing value for key from the trie. If a node was not
+ // found in the database, a trie.MissingNodeError is returned.
TryDelete(key []byte) error
- Commit(onleaf trie.LeafCallback) (common.Hash, error)
+
+ // Hash returns the root hash of the trie. It does not write to the database and
+ // can be used even if the trie doesn't have one.
Hash() common.Hash
+
+ // Commit writes all nodes to the trie's memory database, tracking the internal
+ // and external (for account tries) references.
+ Commit(onleaf trie.LeafCallback) (common.Hash, error)
+
+ // NodeIterator returns an iterator that returns nodes of the trie. Iteration
+ // starts at the key after the given start key.
NodeIterator(startKey []byte) trie.NodeIterator
- GetKey([]byte) []byte // TODO(fjl): remove this when SecureTrie is removed
- Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error
+
+ // Prove constructs a Merkle proof for key. The result contains all encoded nodes
+ // on the path to the value at key. The value itself is also included in the last
+ // node and can be retrieved by verifying the proof.
+ //
+ // If the trie does not contain a value for key, the returned proof contains all
+ // nodes of the longest existing prefix of the key (at least the root), ending
+ // with the node that proves the absence of the key.
+ Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error
}
// NewDatabase creates a backing store for state. The returned database is safe for
-// concurrent use and retains cached trie nodes in memory. The pool is an optional
-// intermediate trie-node memory pool between the low level storage layer and the
-// high level trie abstraction.
+// concurrent use, but does not retain any recent trie nodes in memory. To keep some
+// historical state in memory, use the NewDatabaseWithCache constructor.
func NewDatabase(db ethdb.Database) Database {
+ return NewDatabaseWithCache(db, 0)
+}
+
+// NewDatabaseWithCache creates a backing store for state. The returned database
+// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
+// large memory cache.
+func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
csc, _ := lru.New(codeSizeCacheSize)
return &cachingDB{
- db: trie.NewDatabase(db),
+ db: trie.NewDatabaseWithCache(db, cache),
codeSizeCache: csc,
}
}
type cachingDB struct {
db *trie.Database
- mu sync.Mutex
- pastTries []*trie.SecureTrie
codeSizeCache *lru.Cache
}
-// OpenTrie opens the main account trie.
+// OpenTrie opens the main account trie at a specific root hash.
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
- db.mu.Lock()
- defer db.mu.Unlock()
-
- for i := len(db.pastTries) - 1; i >= 0; i-- {
- if db.pastTries[i].Hash() == root {
- return cachedTrie{db.pastTries[i].Copy(), db}, nil
- }
- }
- tr, err := trie.NewSecure(root, db.db, MaxTrieCacheGen)
- if err != nil {
- return nil, err
- }
- return cachedTrie{tr, db}, nil
-}
-
-func (db *cachingDB) pushTrie(t *trie.SecureTrie) {
- db.mu.Lock()
- defer db.mu.Unlock()
-
- if len(db.pastTries) >= maxPastTries {
- copy(db.pastTries, db.pastTries[1:])
- db.pastTries[len(db.pastTries)-1] = t
- } else {
- db.pastTries = append(db.pastTries, t)
- }
+ return trie.NewSecure(root, db.db)
}
// OpenStorageTrie opens the storage trie of an account.
func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) {
- return trie.NewSecure(root, db.db, 0)
+ return trie.NewSecure(root, db.db)
}
// CopyTrie returns an independent copy of the given trie.
func (db *cachingDB) CopyTrie(t Trie) Trie {
switch t := t.(type) {
- case cachedTrie:
- return cachedTrie{t.SecureTrie.Copy(), db}
case *trie.SecureTrie:
return t.Copy()
default:
@@ -151,9 +154,6 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
return cached.(int), nil
}
code, err := db.ContractCode(addrHash, codeHash)
- if err == nil {
- db.codeSizeCache.Add(codeHash, len(code))
- }
return len(code), err
}
@@ -161,21 +161,3 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
func (db *cachingDB) TrieDB() *trie.Database {
return db.db
}
-
-// cachedTrie inserts its trie into a cachingDB on commit.
-type cachedTrie struct {
- *trie.SecureTrie
- db *cachingDB
-}
-
-func (m cachedTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) {
- root, err := m.SecureTrie.Commit(onleaf)
- if err == nil {
- m.db.pushTrie(m.SecureTrie)
- }
- return root, err
-}
-
-func (m cachedTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
- return m.SecureTrie.Prove(key, fromLevel, proofDb)
-}
diff --git a/core/state/dump.go b/core/state/dump.go
index 46e612850a..d99b580bc4 100644
--- a/core/state/dump.go
+++ b/core/state/dump.go
@@ -20,9 +20,9 @@ import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
type DumpAccount struct {
diff --git a/core/state/iterator.go b/core/state/iterator.go
index 6a5c73d3d1..63ae2b08c4 100644
--- a/core/state/iterator.go
+++ b/core/state/iterator.go
@@ -20,9 +20,9 @@ import (
"bytes"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
// NodeIterator is an iterator to traverse the entire state trie post-order,
diff --git a/core/state/iterator_test.go b/core/state/iterator_test.go
index 9e46c851cd..e6cb329207 100644
--- a/core/state/iterator_test.go
+++ b/core/state/iterator_test.go
@@ -20,8 +20,8 @@ import (
"bytes"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
)
// Tests that the node iterator indeed walks over the entire database contents.
@@ -51,7 +51,9 @@ func TestNodeIteratorCoverage(t *testing.T) {
t.Errorf("state entry not reported %x", hash)
}
}
- for _, key := range db.TrieDB().DiskDB().(*ethdb.MemDatabase).Keys() {
+ it := db.TrieDB().DiskDB().(ethdb.Database).NewIterator(nil, nil)
+ for it.Next() {
+ key := it.Key()
if bytes.HasPrefix(key, []byte("secure-key-")) {
continue
}
diff --git a/core/state/journal.go b/core/state/journal.go
index a89bb3d13a..ac6461df13 100644
--- a/core/state/journal.go
+++ b/core/state/journal.go
@@ -19,7 +19,7 @@ package state
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
type journalEntry interface {
diff --git a/core/state/managed_state.go b/core/state/managed_state.go
index 1390ef4a00..fbd5d29593 100644
--- a/core/state/managed_state.go
+++ b/core/state/managed_state.go
@@ -19,7 +19,7 @@ package state
import (
"sync"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
type account struct {
diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go
index 1cfdd3a890..13f35a8a51 100644
--- a/core/state/managed_state_test.go
+++ b/core/state/managed_state_test.go
@@ -17,16 +17,16 @@
package state
import (
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
var addr = common.BytesToAddress([]byte("test"))
func create() (*ManagedState, *account) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := New(common.Hash{}, NewDatabase(db))
ms := ManageState(statedb)
ms.StateDB.SetNonce(addr, 100)
diff --git a/core/state/state_object.go b/core/state/state_object.go
index b2112bfaec..53ea774d61 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -22,9 +22,9 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
var emptyCodeHash = crypto.Keccak256(nil)
@@ -168,7 +168,24 @@ func (c *stateObject) getTrie(db Database) Trie {
return c.trie
}
-// GetState returns a value in account storage.
+func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
+ value := common.Hash{}
+ // Load from DB in case it is missing.
+ enc, err := self.getTrie(db).TryGet(key[:])
+ if err != nil {
+ self.setError(err)
+ return common.Hash{}
+ }
+ if len(enc) > 0 {
+ _, content, _, err := rlp.Split(enc)
+ if err != nil {
+ self.setError(err)
+ }
+ value.SetBytes(content)
+ }
+ return value
+}
+
func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
value, exists := self.cachedStorage[key]
if exists {
diff --git a/core/state/state_reader.go b/core/state/state_reader.go
index 0296137e53..e451f26a9a 100644
--- a/core/state/state_reader.go
+++ b/core/state/state_reader.go
@@ -1,9 +1,10 @@
package state
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
"math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
func GetLocSimpleVariable(slot uint64) common.Hash {
@@ -31,3 +32,7 @@ func GetLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) comm
arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
return common.BigToHash(arrBig)
}
+
+func GetLocOfStructElement(locOfStruct *big.Int, elementSlotInstruct *big.Int) common.Hash {
+ return common.BigToHash(new(big.Int).Add(locOfStruct, elementSlotInstruct))
+}
diff --git a/core/state/state_test.go b/core/state/state_test.go
index 6d42d63d82..ddc7df61ce 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -18,17 +18,18 @@ package state
import (
"bytes"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
checker "gopkg.in/check.v1"
)
type StateSuite struct {
- db *ethdb.MemDatabase
+ db ethdb.Database
state *StateDB
}
@@ -87,7 +88,7 @@ func (s *StateSuite) TestDump(c *checker.C) {
}
func (s *StateSuite) SetUpTest(c *checker.C) {
- s.db, _ = ethdb.NewMemDatabase()
+ s.db = rawdb.NewMemoryDatabase()
s.state, _ = New(common.Hash{}, NewDatabase(s.db))
}
@@ -133,7 +134,7 @@ func (s *StateSuite) TestSnapshotEmpty(c *checker.C) {
// use testing instead of checker because checker does not support
// printing/logging in tests (-check.vv does not work)
func TestSnapshot2(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
state, _ := New(common.Hash{}, NewDatabase(db))
stateobjaddr0 := toAddr([]byte("so0"))
diff --git a/core/state/statedb.go b/core/state/statedb.go
index b7cb5b9028..07bcf7596b 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -23,12 +23,12 @@ import (
"sort"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
type revision struct {
@@ -83,6 +83,23 @@ type StateDB struct {
lock sync.Mutex
}
+func (self *StateDB) SubRefund(gas uint64) {
+ self.journal = append(self.journal, refundChange{
+ prev: self.refund})
+ if gas > self.refund {
+ panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, self.refund))
+ }
+ self.refund -= gas
+}
+
+func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
+ stateObject := self.getStateObject(addr)
+ if stateObject != nil {
+ return stateObject.GetCommittedState(self.db, hash)
+ }
+ return common.Hash{}
+}
+
// Create a new state from a given trie.
func New(root common.Hash, db Database) (*StateDB, error) {
tr, err := db.OpenTrie(root)
@@ -443,10 +460,10 @@ func (self *StateDB) CreateAccount(addr common.Address) {
}
}
-func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
+func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
so := db.getStateObject(addr)
if so == nil {
- return
+ return nil
}
// When iterating over the storage check the cache first
@@ -462,6 +479,7 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common
cb(key, common.BytesToHash(it.Value))
}
}
+ return nil
}
// Copy creates a deep, independent copy of the state.
@@ -604,7 +622,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
case isDirty:
// Write any contract code associated with the state object
if stateObject.code != nil && stateObject.dirtyCode {
- s.db.TrieDB().Insert(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
+ s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
stateObject.dirtyCode = false
}
// Write any storage changes in the state object to its storage trie.
@@ -631,7 +649,6 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
}
return nil
})
- log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads())
return root, err
}
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index d9e3d9b797..7e7f5343c3 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -20,6 +20,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math"
"math/big"
"math/rand"
@@ -30,16 +31,15 @@ import (
check "gopkg.in/check.v1"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// Tests that updating a state trie does not leak any database writes prior to
// actually committing the state.
func TestUpdateLeaks(t *testing.T) {
// Create an empty state database
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
state, _ := New(common.Hash{}, NewDatabase(db))
// Update it with some accounts
@@ -56,8 +56,10 @@ func TestUpdateLeaks(t *testing.T) {
state.IntermediateRoot(false)
}
// Ensure that no data was leaked into the database
- for _, key := range db.Keys() {
- value, _ := db.Get(key)
+ it := db.NewIterator(nil, nil)
+ for it.Next() {
+ key := it.Key()
+ value := it.Value()
t.Errorf("State leaked into database: %x -> %x", key, value)
}
}
@@ -66,8 +68,8 @@ func TestUpdateLeaks(t *testing.T) {
// only the one right before the commit.
func TestIntermediateLeaks(t *testing.T) {
// Create two state databases, one transitioning to the final state, the other final from the beginning
- transDb, _ := ethdb.NewMemDatabase()
- finalDb, _ := ethdb.NewMemDatabase()
+ transDb := rawdb.NewMemoryDatabase()
+ finalDb := rawdb.NewMemoryDatabase()
transState, _ := New(common.Hash{}, NewDatabase(transDb))
finalState, _ := New(common.Hash{}, NewDatabase(finalDb))
@@ -103,13 +105,17 @@ func TestIntermediateLeaks(t *testing.T) {
if _, err := finalState.Commit(false); err != nil {
t.Fatalf("failed to commit final state: %v", err)
}
- for _, key := range finalDb.Keys() {
+ it := finalDb.NewIterator(nil, nil)
+ for it.Next() {
+ key := it.Key()
if _, err := transDb.Get(key); err != nil {
val, _ := finalDb.Get(key)
t.Errorf("entry missing from the transition database: %x -> %x", key, val)
}
}
- for _, key := range transDb.Keys() {
+ it = transDb.NewIterator(nil, nil)
+ for it.Next() {
+ key := it.Key()
if _, err := finalDb.Get(key); err != nil {
val, _ := transDb.Get(key)
t.Errorf("extra entry in the transition database: %x -> %x", key, val)
@@ -119,10 +125,10 @@ func TestIntermediateLeaks(t *testing.T) {
// TestCopy tests that copying a statedb object indeed makes the original and
// the copy independent of each other. This test is a regression test against
-// https://github.com/ethereum/go-ethereum/pull/15549.
+// https://github.com/XinFinOrg/XDPoSChain/pull/15549.
func TestCopy(t *testing.T) {
// Create a random state test to copy and modify "independently"
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
orig, _ := New(common.Hash{}, NewDatabase(db))
for i := byte(0); i < 255; i++ {
@@ -334,7 +340,7 @@ func (test *snapshotTest) String() string {
func (test *snapshotTest) run() bool {
// Run all actions and create snapshots.
var (
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
state, _ = New(common.Hash{}, NewDatabase(db))
snapshotRevs = make([]int, len(test.snapshots))
sindex = 0
diff --git a/core/state/statedb_utils.go b/core/state/statedb_utils.go
index 665d88df73..6b05bd3197 100644
--- a/core/state/statedb_utils.go
+++ b/core/state/statedb_utils.go
@@ -3,10 +3,10 @@ package state
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/core/state/sync.go b/core/state/sync.go
index 28fcf6ae05..35ee3aefd0 100644
--- a/core/state/sync.go
+++ b/core/state/sync.go
@@ -19,14 +19,15 @@ package state
import (
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
// NewStateSync create a new state trie download scheduler.
-func NewStateSync(root common.Hash, database trie.DatabaseReader) *trie.TrieSync {
- var syncer *trie.TrieSync
+func NewStateSync(root common.Hash, database ethdb.KeyValueReader, bloom *trie.SyncBloom) *trie.Sync {
+ var syncer *trie.Sync
callback := func(leaf []byte, parent common.Hash) error {
var obj Account
if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil {
@@ -36,6 +37,6 @@ func NewStateSync(root common.Hash, database trie.DatabaseReader) *trie.TrieSync
syncer.AddRawEntry(common.BytesToHash(obj.CodeHash), 64, parent)
return nil
}
- syncer = trie.NewTrieSync(root, database, callback)
+ syncer = trie.NewSync(root, database, callback, bloom)
return syncer
}
diff --git a/core/state/sync_test.go b/core/state/sync_test.go
index 8f14a44e7a..e38943ab58 100644
--- a/core/state/sync_test.go
+++ b/core/state/sync_test.go
@@ -21,10 +21,12 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/ethdb/memorydb"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
// testAccount is the data associated with an account used by the state tests.
@@ -38,8 +40,7 @@ type testAccount struct {
// makeTestState create a sample test state to test node-wise reconstruction.
func makeTestState() (Database, common.Hash, []*testAccount) {
// Create an empty state
- diskdb, _ := ethdb.NewMemDatabase()
- db := NewDatabase(diskdb)
+ db := NewDatabase(rawdb.NewMemoryDatabase())
state, _ := New(common.Hash{}, db)
// Fill it with some arbitrary data
@@ -125,8 +126,7 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error {
// Tests that an empty state is not scheduled for syncing.
func TestEmptyStateSync(t *testing.T) {
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
- db, _ := ethdb.NewMemDatabase()
- if req := NewStateSync(empty, db).Missing(1); len(req) != 0 {
+ if req := NewStateSync(empty, rawdb.NewMemoryDatabase(), trie.NewSyncBloom(1, memorydb.New())).Missing(1); len(req) != 0 {
t.Errorf("content requested for empty state: %v", req)
}
}
@@ -136,15 +136,15 @@ func TestEmptyStateSync(t *testing.T) {
func TestIterativeStateSyncIndividual(t *testing.T) { testIterativeStateSync(t, 1) }
func TestIterativeStateSyncBatched(t *testing.T) { testIterativeStateSync(t, 100) }
-func testIterativeStateSync(t *testing.T, batch int) {
+func testIterativeStateSync(t *testing.T, count int) {
// Create a random state to copy
srcDb, srcRoot, srcAccounts := makeTestState()
// Create a destination state and sync with the scheduler
- dstDb, _ := ethdb.NewMemDatabase()
- sched := NewStateSync(srcRoot, dstDb)
+ dstDb := rawdb.NewMemoryDatabase()
+ sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb))
- queue := append([]common.Hash{}, sched.Missing(batch)...)
+ queue := append([]common.Hash{}, sched.Missing(count)...)
for len(queue) > 0 {
results := make([]trie.SyncResult, len(queue))
for i, hash := range queue {
@@ -157,10 +157,12 @@ func testIterativeStateSync(t *testing.T, batch int) {
if _, index, err := sched.Process(results); err != nil {
t.Fatalf("failed to process result #%d: %v", index, err)
}
- if index, err := sched.Commit(dstDb); err != nil {
- t.Fatalf("failed to commit data #%d: %v", index, err)
+ batch := dstDb.NewBatch()
+ if err := sched.Commit(batch); err != nil {
+ t.Fatalf("failed to commit data: %v", err)
}
- queue = append(queue[:0], sched.Missing(batch)...)
+ batch.Write()
+ queue = append(queue[:0], sched.Missing(count)...)
}
// Cross check that the two states are in sync
checkStateAccounts(t, dstDb, srcRoot, srcAccounts)
@@ -173,8 +175,8 @@ func TestIterativeDelayedStateSync(t *testing.T) {
srcDb, srcRoot, srcAccounts := makeTestState()
// Create a destination state and sync with the scheduler
- dstDb, _ := ethdb.NewMemDatabase()
- sched := NewStateSync(srcRoot, dstDb)
+ dstDb := rawdb.NewMemoryDatabase()
+ sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb))
queue := append([]common.Hash{}, sched.Missing(0)...)
for len(queue) > 0 {
@@ -190,9 +192,11 @@ func TestIterativeDelayedStateSync(t *testing.T) {
if _, index, err := sched.Process(results); err != nil {
t.Fatalf("failed to process result #%d: %v", index, err)
}
- if index, err := sched.Commit(dstDb); err != nil {
- t.Fatalf("failed to commit data #%d: %v", index, err)
+ batch := dstDb.NewBatch()
+ if err := sched.Commit(batch); err != nil {
+ t.Fatalf("failed to commit data: %v", err)
}
+ batch.Write()
queue = append(queue[len(results):], sched.Missing(0)...)
}
// Cross check that the two states are in sync
@@ -205,16 +209,16 @@ func TestIterativeDelayedStateSync(t *testing.T) {
func TestIterativeRandomStateSyncIndividual(t *testing.T) { testIterativeRandomStateSync(t, 1) }
func TestIterativeRandomStateSyncBatched(t *testing.T) { testIterativeRandomStateSync(t, 100) }
-func testIterativeRandomStateSync(t *testing.T, batch int) {
+func testIterativeRandomStateSync(t *testing.T, count int) {
// Create a random state to copy
srcDb, srcRoot, srcAccounts := makeTestState()
// Create a destination state and sync with the scheduler
- dstDb, _ := ethdb.NewMemDatabase()
- sched := NewStateSync(srcRoot, dstDb)
+ dstDb := rawdb.NewMemoryDatabase()
+ sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb))
queue := make(map[common.Hash]struct{})
- for _, hash := range sched.Missing(batch) {
+ for _, hash := range sched.Missing(count) {
queue[hash] = struct{}{}
}
for len(queue) > 0 {
@@ -231,11 +235,13 @@ func testIterativeRandomStateSync(t *testing.T, batch int) {
if _, index, err := sched.Process(results); err != nil {
t.Fatalf("failed to process result #%d: %v", index, err)
}
- if index, err := sched.Commit(dstDb); err != nil {
- t.Fatalf("failed to commit data #%d: %v", index, err)
+ batch := dstDb.NewBatch()
+ if err := sched.Commit(batch); err != nil {
+ t.Fatalf("failed to commit data: %v", err)
}
+ batch.Write()
queue = make(map[common.Hash]struct{})
- for _, hash := range sched.Missing(batch) {
+ for _, hash := range sched.Missing(count) {
queue[hash] = struct{}{}
}
}
@@ -250,8 +256,8 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) {
srcDb, srcRoot, srcAccounts := makeTestState()
// Create a destination state and sync with the scheduler
- dstDb, _ := ethdb.NewMemDatabase()
- sched := NewStateSync(srcRoot, dstDb)
+ dstDb := rawdb.NewMemoryDatabase()
+ sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb))
queue := make(map[common.Hash]struct{})
for _, hash := range sched.Missing(0) {
@@ -277,9 +283,11 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) {
if _, index, err := sched.Process(results); err != nil {
t.Fatalf("failed to process result #%d: %v", index, err)
}
- if index, err := sched.Commit(dstDb); err != nil {
- t.Fatalf("failed to commit data #%d: %v", index, err)
+ batch := dstDb.NewBatch()
+ if err := sched.Commit(batch); err != nil {
+ t.Fatalf("failed to commit data: %v", err)
}
+ batch.Write()
for _, hash := range sched.Missing(0) {
queue[hash] = struct{}{}
}
@@ -297,8 +305,8 @@ func TestIncompleteStateSync(t *testing.T) {
checkTrieConsistency(srcDb.TrieDB().DiskDB().(ethdb.Database), srcRoot)
// Create a destination state and sync with the scheduler
- dstDb, _ := ethdb.NewMemDatabase()
- sched := NewStateSync(srcRoot, dstDb)
+ dstDb := rawdb.NewMemoryDatabase()
+ sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb))
added := []common.Hash{}
queue := append([]common.Hash{}, sched.Missing(1)...)
@@ -316,9 +324,11 @@ func TestIncompleteStateSync(t *testing.T) {
if _, index, err := sched.Process(results); err != nil {
t.Fatalf("failed to process result #%d: %v", index, err)
}
- if index, err := sched.Commit(dstDb); err != nil {
- t.Fatalf("failed to commit data #%d: %v", index, err)
+ batch := dstDb.NewBatch()
+ if err := sched.Commit(batch); err != nil {
+ t.Fatalf("failed to commit data: %v", err)
}
+ batch.Write()
for _, result := range results {
added = append(added, result.Hash)
}
diff --git a/core/state/trc21_reader.go b/core/state/trc21_reader.go
index abf59a94fe..6e0e363617 100644
--- a/core/state/trc21_reader.go
+++ b/core/state/trc21_reader.go
@@ -2,9 +2,9 @@ package state
import (
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/hashicorp/golang-lru"
"math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
)
var (
@@ -107,6 +107,7 @@ func ValidateTRC21Tx(statedb *StateDB, from common.Address, token common.Address
slotBalanceTrc21 := SlotTRC21Token["balances"]
balanceKey := GetLocMappingAtKey(from.Hash(), slotBalanceTrc21)
balanceHash := statedb.GetState(token, common.BigToHash(balanceKey))
+
if !common.EmptyHash(balanceHash) {
balance := balanceHash.Big()
minFeeTokenKey := GetLocSimpleVariable(SlotTRC21Token["minFee"])
@@ -127,7 +128,14 @@ func ValidateTRC21Tx(statedb *StateDB, from common.Address, token common.Address
} else {
return true
}
+ } else {
+ // we both accept tx with balance = 0 and fee = 0
+ minFeeTokenKey := GetLocSimpleVariable(SlotTRC21Token["minFee"])
+ if !common.EmptyHash(minFeeTokenKey) {
+ return true
+ }
}
+
return false
}
diff --git a/core/state_processor.go b/core/state_processor.go
index 41de37991b..fa44dea572 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -18,18 +18,23 @@ package core
import (
"fmt"
+
"math/big"
"runtime"
+ "strings"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/log"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/consensus/misc"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// StateProcessor is a basic Processor, which takes care of transitioning
@@ -62,7 +67,7 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
// Process returns the receipts and logs accumulated during the process and
// returns the amount of gas that was used in the process. If any of the
// transactions failed to execute due to insufficient gas it will return an error.
-func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) {
+func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) {
var (
receipts types.Receipts
usedGas = new(uint64)
@@ -77,6 +82,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if common.TIPSigning.Cmp(header.Number) == 0 {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
+ parentState := statedb.Copy()
InitSignerInTransactions(p.config, header, block.Transactions())
balanceUpdated := map[common.Address]*big.Int{}
totalFeeUsed := big.NewInt(0)
@@ -92,8 +98,22 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return nil, nil, 0, fmt.Errorf("Block contains transaction with receiver in black-list: %v", tx.To().Hex())
}
}
+ // validate minFee slot for XDCZ
+ if tx.IsXDCZApplyTransaction() {
+ copyState := statedb.Copy()
+ if err := ValidateXDCZApplyTransaction(p.bc, block.Number(), copyState, common.BytesToAddress(tx.Data()[4:])); err != nil {
+ return nil, nil, 0, err
+ }
+ }
+ // validate balance slot, token decimal for XDCX
+ if tx.IsXDCXApplyTransaction() {
+ copyState := statedb.Copy()
+ if err := ValidateXDCXApplyTransaction(p.bc, block.Number(), copyState, common.BytesToAddress(tx.Data()[4:])); err != nil {
+ return nil, nil, 0, err
+ }
+ }
statedb.Prepare(tx.Hash(), block.Hash(), i)
- receipt, gas, err, tokenFeeUsed := ApplyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
+ receipt, gas, err, tokenFeeUsed := ApplyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, tradingState, header, tx, usedGas, cfg)
if err != nil {
return nil, nil, 0, err
}
@@ -111,11 +131,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
}
state.UpdateTRC21Fee(statedb, balanceUpdated, totalFeeUsed)
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
- p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts)
+ p.engine.Finalize(p.bc, header, statedb, parentState, block.Transactions(), block.Uncles(), receipts)
return receipts, allLogs, *usedGas, nil
}
-func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, statedb *state.StateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) {
+func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) {
block := cBlock.block
var (
receipts types.Receipts
@@ -134,6 +154,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
if cBlock.stop {
return nil, nil, 0, ErrStopPreparingBlock
}
+ parentState := statedb.Copy()
InitSignerInTransactions(p.config, header, block.Transactions())
balanceUpdated := map[common.Address]*big.Int{}
totalFeeUsed := big.NewInt(0)
@@ -155,8 +176,22 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
return nil, nil, 0, fmt.Errorf("Block contains transaction with receiver in black-list: %v", tx.To().Hex())
}
}
+ // validate minFee slot for XDCZ
+ if tx.IsXDCZApplyTransaction() {
+ copyState := statedb.Copy()
+ if err := ValidateXDCZApplyTransaction(p.bc, block.Number(), copyState, common.BytesToAddress(tx.Data()[4:])); err != nil {
+ return nil, nil, 0, err
+ }
+ }
+ // validate balance slot, token decimal for XDCX
+ if tx.IsXDCXApplyTransaction() {
+ copyState := statedb.Copy()
+ if err := ValidateXDCXApplyTransaction(p.bc, block.Number(), copyState, common.BytesToAddress(tx.Data()[4:])); err != nil {
+ return nil, nil, 0, err
+ }
+ }
statedb.Prepare(tx.Hash(), block.Hash(), i)
- receipt, gas, err, tokenFeeUsed := ApplyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
+ receipt, gas, err, tokenFeeUsed := ApplyTransaction(p.config, balanceFee, p.bc, nil, gp, statedb, tradingState, header, tx, usedGas, cfg)
if err != nil {
return nil, nil, 0, err
}
@@ -177,7 +212,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
}
state.UpdateTRC21Fee(statedb, balanceUpdated, totalFeeUsed)
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
- p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts)
+ p.engine.Finalize(p.bc, header, statedb, parentState, block.Transactions(), block.Uncles(), receipts)
return receipts, allLogs, *usedGas, nil
}
@@ -185,17 +220,31 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
// and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
-func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*big.Int, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error, bool) {
+func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*big.Int, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, XDCxState *tradingstate.TradingStateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error, bool) {
if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPSigning(header.Number) {
return ApplySignTransaction(config, statedb, header, tx, usedGas)
}
+ if tx.To() != nil && tx.To().String() == common.TradingStateAddr && config.IsTIPXDCX(header.Number) {
+ return ApplyEmptyTransaction(config, statedb, header, tx, usedGas)
+ }
+ if tx.To() != nil && tx.To().String() == common.XDCXLendingAddress && config.IsTIPXDCX(header.Number) {
+ return ApplyEmptyTransaction(config, statedb, header, tx, usedGas)
+ }
+ if tx.IsTradingTransaction() && config.IsTIPXDCX(header.Number) {
+ return ApplyEmptyTransaction(config, statedb, header, tx, usedGas)
+ }
+
+ if tx.IsLendingFinalizedTradeTransaction() && config.IsTIPXDCX(header.Number) {
+ return ApplyEmptyTransaction(config, statedb, header, tx, usedGas)
+ }
+
var balanceFee *big.Int
if tx.To() != nil {
if value, ok := tokensFee[*tx.To()]; ok {
balanceFee = value
}
}
- msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), balanceFee,header.Number)
+ msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), balanceFee, header.Number)
if err != nil {
return nil, 0, err, false
}
@@ -203,7 +252,7 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
context := NewEVMContext(msg, header, bc, author)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
- vmenv := vm.NewEVM(context, statedb, config, cfg)
+ vmenv := vm.NewEVM(context, statedb, XDCxState, config, cfg)
// If we don't have an explicit author (i.e. not mining), extract from the header
var beneficiary common.Address
@@ -215,8 +264,153 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
coinbaseOwner := statedb.GetOwner(beneficiary)
+ // Bypass blacklist address
+ maxBlockNumber := new(big.Int).SetInt64(9147459)
+ if header.Number.Cmp(maxBlockNumber) <= 0 {
+ addrMap := make(map[string]string)
+ addrMap["0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"] = "29410"
+ addrMap["0x5ac26105b35ea8935be382863a70281ec7a985e9"] = "23551"
+ addrMap["0x09c4f991a41e7ca0645d7dfbfee160b55e562ea4"] = "25821"
+ addrMap["0xb3157bbc5b401a45d6f60b106728bb82ebaa585b"] = "20051"
+ addrMap["0x741277a8952128d5c2ffe0550f5001e4c8247674"] = "23937"
+ addrMap["0x10ba49c1caa97d74b22b3e74493032b180cebe01"] = "27320"
+ addrMap["0x07048d51d9e6179578a6e3b9ee28cdc183b865e4"] = "29758"
+ addrMap["0x4b899001d73c7b4ec404a771d37d9be13b8983de"] = "26148"
+ addrMap["0x85cb320a9007f26b7652c19a2a65db1da2d0016f"] = "27216"
+ addrMap["0x06869dbd0e3a2ea37ddef832e20fa005c6f0ca39"] = "29449"
+ addrMap["0x82e48bc7e2c93d89125428578fb405947764ad7c"] = "28084"
+ addrMap["0x1f9a78534d61732367cbb43fc6c89266af67c989"] = "29287"
+ addrMap["0x7c3b1fa91df55ff7af0cad9e0399384dc5c6641b"] = "21574"
+ addrMap["0x5888dc1ceb0ff632713486b9418e59743af0fd20"] = "28836"
+ addrMap["0xa512fa1c735fc3cc635624d591dd9ea1ce339ca5"] = "25515"
+ addrMap["0x0832517654c7b7e36b1ef45d76de70326b09e2c7"] = "22873"
+ addrMap["0xca14e3c4c78bafb60819a78ff6e6f0f709d2aea7"] = "24968"
+ addrMap["0x652ce195a23035114849f7642b0e06647d13e57a"] = "24091"
+ addrMap["0x29a79f00f16900999d61b6e171e44596af4fb5ae"] = "20790"
+ addrMap["0xf9fd1c2b0af0d91b0b6754e55639e3f8478dd04a"] = "23331"
+ addrMap["0xb835710c9901d5fe940ef1b99ed918902e293e35"] = "28273"
+ addrMap["0x04dd29ce5c253377a9a3796103ea0d9a9e514153"] = "29956"
+ addrMap["0x2b4b56846eaf05c1fd762b5e1ac802efd0ab871c"] = "24911"
+ addrMap["0x1d1f909f6600b23ce05004f5500ab98564717996"] = "25637"
+ addrMap["0x0dfdcebf80006dc9ab7aae8c216b51c6b6759e86"] = "26378"
+ addrMap["0x2b373890a28e5e46197fbc04f303bbfdd344056f"] = "21109"
+ addrMap["0xa8a3ef3dc5d8e36aee76f3671ec501ec31e28254"] = "22072"
+ addrMap["0x4f3d18136fe2b5665c29bdaf74591fc6625ef427"] = "21650"
+ addrMap["0x175d728b0e0f1facb5822a2e0c03bde93596e324"] = "21588"
+ addrMap["0xd575c2611984fcd79513b80ab94f59dc5bab4916"] = "28971"
+ addrMap["0x0579337873c97c4ba051310236ea847f5be41bc0"] = "28344"
+ addrMap["0xed12a519cc15b286920fc15fd86106b3e6a16218"] = "24443"
+ addrMap["0x492d26d852a0a0a2982bb40ec86fe394488c419e"] = "26623"
+ addrMap["0xce5c7635d02dc4e1d6b46c256cae6323be294a32"] = "28459"
+ addrMap["0x8b94db158b5e78a6c032c7e7c9423dec62c8b11c"] = "21803"
+ addrMap["0x0e7c48c085b6b0aa7ca6e4cbcc8b9a92dc270eb4"] = "21739"
+ addrMap["0x206e6508462033ef8425edc6c10789d241d49acb"] = "21883"
+ addrMap["0x7710e7b7682f26cb5a1202e1cff094fbf7777758"] = "28907"
+ addrMap["0xcb06f949313b46bbf53b8e6b2868a0c260ff9385"] = "28932"
+ addrMap["0xf884e43533f61dc2997c0e19a6eff33481920c00"] = "27780"
+ addrMap["0x8b635ef2e4c8fe21fc2bda027eb5f371d6aa2fc1"] = "23115"
+ addrMap["0x10f01a27cf9b29d02ce53497312b96037357a361"] = "22716"
+ addrMap["0x693dd49b0ed70f162d733cf20b6c43dc2a2b4d95"] = "20020"
+ addrMap["0xe0bec72d1c2a7a7fb0532cdfac44ebab9f6f41ee"] = "23071"
+ addrMap["0xc8793633a537938cb49cdbbffd45428f10e45b64"] = "24652"
+ addrMap["0x0d07a6cbbe9fa5c4f154e5623bfe47fb4d857d8e"] = "21907"
+ addrMap["0xd4080b289da95f70a586610c38268d8d4cf1e4c4"] = "22719"
+ addrMap["0x8bcfb0caf41f0aa1b548cae76dcdd02e33866a1b"] = "29062"
+ addrMap["0xabfef22b92366d3074676e77ea911ccaabfb64c1"] = "23110"
+ addrMap["0xcc4df7a32faf3efba32c9688def5ccf9fefe443d"] = "21397"
+ addrMap["0x7ec1e48a582475f5f2b7448a86c4ea7a26ea36f8"] = "23105"
+ addrMap["0xe3de67289080f63b0c2612844256a25bb99ac0ad"] = "29721"
+ addrMap["0x3ba623300cf9e48729039b3c9e0dee9b785d636e"] = "25917"
+ addrMap["0x402f2cfc9c8942f5e7a12c70c625d07a5d52fe29"] = "24712"
+ addrMap["0xd62358d42afbde095a4ca868581d85f9adcc3d61"] = "24449"
+ addrMap["0x3969f86acb733526cd61e3c6e3b4660589f32bc6"] = "29579"
+ addrMap["0x67615413d7cdadb2c435a946aec713a9a9794d39"] = "26333"
+ addrMap["0xfe685f43acc62f92ab01a8da80d76455d39d3cb3"] = "29825"
+ addrMap["0x3538a544021c07869c16b764424c5987409cba48"] = "22746"
+ addrMap["0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"] = "23734"
+
+ blockMap := make(map[int64]string)
+
+ blockMap[9073579] = "0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"
+ blockMap[9147130] = "0x5ac26105b35ea8935be382863a70281ec7a985e9"
+ blockMap[9147195] = "0x09c4f991a41e7ca0645d7dfbfee160b55e562ea4"
+ blockMap[9147200] = "0xb3157bbc5b401a45d6f60b106728bb82ebaa585b"
+ blockMap[9147206] = "0x741277a8952128d5c2ffe0550f5001e4c8247674"
+ blockMap[9147212] = "0x10ba49c1caa97d74b22b3e74493032b180cebe01"
+ blockMap[9147217] = "0x07048d51d9e6179578a6e3b9ee28cdc183b865e4"
+ blockMap[9147223] = "0x4b899001d73c7b4ec404a771d37d9be13b8983de"
+ blockMap[9147229] = "0x85cb320a9007f26b7652c19a2a65db1da2d0016f"
+ blockMap[9147234] = "0x06869dbd0e3a2ea37ddef832e20fa005c6f0ca39"
+ blockMap[9147240] = "0x82e48bc7e2c93d89125428578fb405947764ad7c"
+ blockMap[9147246] = "0x1f9a78534d61732367cbb43fc6c89266af67c989"
+ blockMap[9147251] = "0x7c3b1fa91df55ff7af0cad9e0399384dc5c6641b"
+ blockMap[9147257] = "0x5888dc1ceb0ff632713486b9418e59743af0fd20"
+ blockMap[9147263] = "0xa512fa1c735fc3cc635624d591dd9ea1ce339ca5"
+ blockMap[9147268] = "0x0832517654c7b7e36b1ef45d76de70326b09e2c7"
+ blockMap[9147274] = "0xca14e3c4c78bafb60819a78ff6e6f0f709d2aea7"
+ blockMap[9147279] = "0x652ce195a23035114849f7642b0e06647d13e57a"
+ blockMap[9147285] = "0x29a79f00f16900999d61b6e171e44596af4fb5ae"
+ blockMap[9147291] = "0xf9fd1c2b0af0d91b0b6754e55639e3f8478dd04a"
+ blockMap[9147296] = "0xb835710c9901d5fe940ef1b99ed918902e293e35"
+ blockMap[9147302] = "0x04dd29ce5c253377a9a3796103ea0d9a9e514153"
+ blockMap[9147308] = "0x2b4b56846eaf05c1fd762b5e1ac802efd0ab871c"
+ blockMap[9147314] = "0x1d1f909f6600b23ce05004f5500ab98564717996"
+ blockMap[9147319] = "0x0dfdcebf80006dc9ab7aae8c216b51c6b6759e86"
+ blockMap[9147325] = "0x2b373890a28e5e46197fbc04f303bbfdd344056f"
+ blockMap[9147330] = "0xa8a3ef3dc5d8e36aee76f3671ec501ec31e28254"
+ blockMap[9147336] = "0x4f3d18136fe2b5665c29bdaf74591fc6625ef427"
+ blockMap[9147342] = "0x175d728b0e0f1facb5822a2e0c03bde93596e324"
+ blockMap[9145281] = "0xd575c2611984fcd79513b80ab94f59dc5bab4916"
+ blockMap[9145315] = "0x0579337873c97c4ba051310236ea847f5be41bc0"
+ blockMap[9145341] = "0xed12a519cc15b286920fc15fd86106b3e6a16218"
+ blockMap[9145367] = "0x492d26d852a0a0a2982bb40ec86fe394488c419e"
+ blockMap[9145386] = "0xce5c7635d02dc4e1d6b46c256cae6323be294a32"
+ blockMap[9145414] = "0x8b94db158b5e78a6c032c7e7c9423dec62c8b11c"
+ blockMap[9145436] = "0x0e7c48c085b6b0aa7ca6e4cbcc8b9a92dc270eb4"
+ blockMap[9145463] = "0x206e6508462033ef8425edc6c10789d241d49acb"
+ blockMap[9145493] = "0x7710e7b7682f26cb5a1202e1cff094fbf7777758"
+ blockMap[9145519] = "0xcb06f949313b46bbf53b8e6b2868a0c260ff9385"
+ blockMap[9145549] = "0xf884e43533f61dc2997c0e19a6eff33481920c00"
+ blockMap[9147352] = "0x8b635ef2e4c8fe21fc2bda027eb5f371d6aa2fc1"
+ blockMap[9147357] = "0x10f01a27cf9b29d02ce53497312b96037357a361"
+ blockMap[9147363] = "0x693dd49b0ed70f162d733cf20b6c43dc2a2b4d95"
+ blockMap[9147369] = "0xe0bec72d1c2a7a7fb0532cdfac44ebab9f6f41ee"
+ blockMap[9147375] = "0xc8793633a537938cb49cdbbffd45428f10e45b64"
+ blockMap[9147380] = "0x0d07a6cbbe9fa5c4f154e5623bfe47fb4d857d8e"
+ blockMap[9147386] = "0xd4080b289da95f70a586610c38268d8d4cf1e4c4"
+ blockMap[9147392] = "0x8bcfb0caf41f0aa1b548cae76dcdd02e33866a1b"
+ blockMap[9147397] = "0xabfef22b92366d3074676e77ea911ccaabfb64c1"
+ blockMap[9147403] = "0xcc4df7a32faf3efba32c9688def5ccf9fefe443d"
+ blockMap[9147408] = "0x7ec1e48a582475f5f2b7448a86c4ea7a26ea36f8"
+ blockMap[9147414] = "0xe3de67289080f63b0c2612844256a25bb99ac0ad"
+ blockMap[9147420] = "0x3ba623300cf9e48729039b3c9e0dee9b785d636e"
+ blockMap[9147425] = "0x402f2cfc9c8942f5e7a12c70c625d07a5d52fe29"
+ blockMap[9147431] = "0xd62358d42afbde095a4ca868581d85f9adcc3d61"
+ blockMap[9147437] = "0x3969f86acb733526cd61e3c6e3b4660589f32bc6"
+ blockMap[9147442] = "0x67615413d7cdadb2c435a946aec713a9a9794d39"
+ blockMap[9147448] = "0xfe685f43acc62f92ab01a8da80d76455d39d3cb3"
+ blockMap[9147453] = "0x3538a544021c07869c16b764424c5987409cba48"
+ blockMap[9147459] = "0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"
+
+ addrFrom := msg.From().Hex()
+
+ currentBlockNumber := header.Number.Int64()
+ if addr, ok := blockMap[currentBlockNumber]; ok {
+ if strings.ToLower(addr) == strings.ToLower(addrFrom) {
+ bal := addrMap[addr]
+ hBalance := new(big.Int)
+ hBalance.SetString(bal+"000000000000000000", 10)
+ log.Info("address", addr, "with_balance", bal, "XDC")
+ addrBin := common.HexToAddress(addr)
+ statedb.SetBalance(addrBin, hBalance)
+ }
+ }
+ }
+ // End Bypass blacklist address
+
// Apply the transaction to the current state (included in the env)
_, gas, failed, err := ApplyMessage(vmenv, msg, gp, coinbaseOwner)
+
if err != nil {
return nil, 0, err, false
}
@@ -282,6 +476,30 @@ func ApplySignTransaction(config *params.ChainConfig, statedb *state.StateDB, he
return receipt, 0, nil, false
}
+func ApplyEmptyTransaction(config *params.ChainConfig, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error, bool) {
+ // Update the state with pending changes
+ var root []byte
+ if config.IsByzantium(header.Number) {
+ statedb.Finalise(true)
+ } else {
+ root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
+ }
+ // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
+ // based on the eip phase, we're passing wether the root touch-delete accounts.
+ receipt := types.NewReceipt(root, false, *usedGas)
+ receipt.TxHash = tx.Hash()
+ receipt.GasUsed = 0
+ // if the transaction created a contract, store the creation address in the receipt.
+ // Set the receipt logs and create a bloom for filtering
+ log := &types.Log{}
+ log.Address = *tx.To()
+ log.BlockNumber = header.Number.Uint64()
+ statedb.AddLog(log)
+ receipt.Logs = statedb.GetLogs(tx.Hash())
+ receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
+ return receipt, 0, nil, false
+}
+
func InitSignerInTransactions(config *params.ChainConfig, header *types.Header, txs types.Transactions) {
nWorker := runtime.NumCPU()
signer := types.MakeSigner(config, header.Number)
diff --git a/core/state_transition.go b/core/state_transition.go
index 5c9595297e..ca29fa3dd6 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -21,10 +21,10 @@ import (
"math"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
var (
@@ -242,7 +242,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
vmerr error
)
// for debugging purpose
- // TODO: clean it after fixing the issue https://github.com/XDCchain/XDCchain/issues/401
+ // TODO: clean it after fixing the issue https://github.com/XinFinOrg/XDPoSChain/issues/401
var contractAction string
nonce := uint64(1)
if contractCreation {
diff --git a/core/token_validator.go b/core/token_validator.go
new file mode 100644
index 0000000000..277abb8b86
--- /dev/null
+++ b/core/token_validator.go
@@ -0,0 +1,220 @@
+// Copyright (c) 2018 XDPoSChain
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+
+package core
+
+import (
+ "fmt"
+ "math/big"
+ "math/rand"
+ "strings"
+
+ ethereum "github.com/XinFinOrg/XDPoSChain"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/log"
+)
+
+const (
+ balanceOfFunction = "balanceOf"
+ minFeeFunction = "minFee"
+ getDecimalFunction = "decimals"
+)
+
+// callmsg implements core.Message to allow passing it as a transaction simulator.
+type callmsg struct {
+ ethereum.CallMsg
+}
+
+func (m callmsg) From() common.Address { return m.CallMsg.From }
+func (m callmsg) Nonce() uint64 { return 0 }
+func (m callmsg) CheckNonce() bool { return false }
+func (m callmsg) To() *common.Address { return m.CallMsg.To }
+func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
+func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
+func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
+func (m callmsg) Data() []byte { return m.CallMsg.Data }
+func (m callmsg) BalanceTokenFee() *big.Int { return m.CallMsg.BalanceTokenFee }
+
+type SimulatedBackend interface {
+ CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, statedb *state.StateDB) ([]byte, error)
+}
+
+// GetTokenAbi return token abi
+func GetTokenAbi(tokenAbi string) (*abi.ABI, error) {
+ contractABI, err := abi.JSON(strings.NewReader(tokenAbi))
+ if err != nil {
+ return nil, err
+ }
+ return &contractABI, nil
+}
+
+// RunContract run smart contract
+func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractAddr common.Address, abi *abi.ABI, method string, args ...interface{}) (interface{}, error) {
+ input, err := abi.Pack(method, args...)
+ if err != nil {
+ return nil, err
+ }
+ fakeCaller := common.HexToAddress("0x0000000000000000000000000000000000000001")
+ statedb.SetBalance(fakeCaller, common.BasePrice)
+ msg := ethereum.CallMsg{To: &contractAddr, Data: input, From: fakeCaller}
+ result, err := CallContractWithState(msg, chain, statedb)
+ if err != nil {
+ return nil, err
+ }
+ var unpackResult interface{}
+ err = abi.Unpack(&unpackResult, method, result)
+ if err != nil {
+ return nil, err
+ }
+ return unpackResult, nil
+}
+
+//FIXME: please use copyState for this function
+// CallContractWithState executes a contract call at the given state.
+func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, statedb *state.StateDB) ([]byte, error) {
+ // Ensure message is initialized properly.
+ call.GasPrice = big.NewInt(0)
+
+ if call.Gas == 0 {
+ call.Gas = 1000000
+ }
+ if call.Value == nil {
+ call.Value = new(big.Int)
+ }
+ // Execute the call.
+ msg := callmsg{call}
+ feeCapacity := state.GetTRC21FeeCapacityFromState(statedb)
+ if msg.To() != nil {
+ if value, ok := feeCapacity[*msg.To()]; ok {
+ msg.CallMsg.BalanceTokenFee = value
+ }
+ }
+ evmContext := NewEVMContext(msg, chain.CurrentHeader(), chain, nil)
+ // Create a new environment which holds all relevant information
+ // about the transaction and calling mechanisms.
+ vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{})
+ gaspool := new(GasPool).AddGas(1000000)
+ owner := common.Address{}
+ rval, _, _, err := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
+ if err != nil {
+ return nil, err
+ }
+ return rval, err
+}
+
+// make sure that balance of token is at slot 0
+func ValidateXDCXApplyTransaction(chain consensus.ChainContext, blockNumber *big.Int, copyState *state.StateDB, tokenAddr common.Address) error {
+ if blockNumber == nil || blockNumber.Sign() <= 0 {
+ blockNumber = chain.CurrentHeader().Number
+ }
+ if !chain.Config().IsTIPXDCX(blockNumber) {
+ return nil
+ }
+ contractABI, err := GetTokenAbi(contract.TRC21ABI)
+ if err != nil {
+ return fmt.Errorf("ValidateXDCXApplyTransaction: cannot parse ABI. Err: %v", err)
+ }
+ if err := ValidateBalanceSlot(chain, copyState, tokenAddr, contractABI); err != nil {
+ return err
+ }
+ if err := ValidateTokenDecimal(chain, copyState, tokenAddr, contractABI); err != nil {
+ return err
+ }
+ return nil
+}
+
+// make sure that balance of token is at slot 0
+// make sure that minFee of token is at slot 1
+func ValidateXDCZApplyTransaction(chain consensus.ChainContext, blockNumber *big.Int, copyState *state.StateDB, tokenAddr common.Address) error {
+ if blockNumber == nil || blockNumber.Sign() <= 0 {
+ blockNumber = chain.CurrentHeader().Number
+ }
+ if !chain.Config().IsTIPXDCX(blockNumber) {
+ return nil
+ }
+ contractABI, err := GetTokenAbi(contract.TRC21ABI)
+ if err != nil {
+ return fmt.Errorf("ValidateXDCZApplyTransaction: cannot parse ABI. Err: %v", err)
+ }
+ // verify balance slot
+ if err := ValidateBalanceSlot(chain, copyState, tokenAddr, contractABI); err != nil {
+ return err
+ }
+
+ // validate minFee slot
+ if err := ValidateMinFeeSlot(chain, copyState, tokenAddr, contractABI); err != nil {
+ return err
+ }
+ return nil
+}
+
+func SetRandomBalance(copyState *state.StateDB, tokenAddr, addr common.Address, randomValue *big.Int) {
+ slotBalanceTrc21 := state.SlotTRC21Token["balances"]
+ balanceKey := state.GetLocMappingAtKey(addr.Hash(), slotBalanceTrc21)
+ copyState.SetState(tokenAddr, common.BigToHash(balanceKey), common.BytesToHash(randomValue.Bytes()))
+}
+
+func ValidateBalanceSlot(chain consensus.ChainContext, copyState *state.StateDB, tokenAddr common.Address, contractABI *abi.ABI) error {
+ randBalance := new(big.Int).SetInt64(int64(rand.Intn(1000000000)))
+ addr := common.HexToAddress("0x0000000000000000000000000000000000000123")
+ SetRandomBalance(copyState, tokenAddr, addr, randBalance)
+ result, err := RunContract(chain, copyState, tokenAddr, contractABI, balanceOfFunction, addr)
+
+ if err != nil || result == nil {
+ return fmt.Errorf("cannot get balance at slot %v . Token: %s . Err: %v", state.SlotTRC21Token["balances"], tokenAddr.Hex(), err)
+ }
+ balance, ok := result.(*big.Int)
+ if !ok {
+ return fmt.Errorf("invalid balance at slot %v . Token: %s . GotBalance: %v . ResultType: %T", state.SlotTRC21Token["balances"], tokenAddr.Hex(), result, result)
+ }
+ if balance.Cmp(randBalance) != 0 {
+ log.Debug("invalid balance slot", "balance_set_at_slot_0", randBalance, "balance_get_from_abi", balance)
+ return fmt.Errorf("invalid balance slot. Token: %s", tokenAddr.Hex())
+ }
+ return nil
+}
+
+func ValidateMinFeeSlot(chain consensus.ChainContext, copyState *state.StateDB, tokenAddr common.Address, contractABI *abi.ABI) error {
+ randomValue := new(big.Int).SetInt64(int64(rand.Intn(1000000000)))
+ slotMinFeeTrc21 := state.SlotTRC21Token["minFee"]
+ copyState.SetState(tokenAddr, common.BigToHash(new(big.Int).SetUint64(slotMinFeeTrc21)), common.BytesToHash(randomValue.Bytes()))
+
+ result, err := RunContract(chain, copyState, tokenAddr, contractABI, minFeeFunction)
+ if err != nil || result == nil {
+ return fmt.Errorf("cannot get minFee at slot %v . Token: %s. Err: %v", state.SlotTRC21Token["minFee"], tokenAddr.Hex(), err)
+ }
+ minFee, ok := result.(*big.Int)
+ if !ok {
+ return fmt.Errorf("invalid minFee at slot %v . Token: %s . GotMinFee: %v . ResultType: %T", state.SlotTRC21Token["minFee"], tokenAddr.Hex(), result, result)
+ }
+ if minFee.Cmp(randomValue) != 0 {
+ log.Debug("invalid minFee slot", "minFee_set_at_slot_1", randomValue, "minFee_get_from_abi", minFee)
+ return fmt.Errorf("invalid minFee slot. Token: %s", tokenAddr.Hex())
+ }
+ return nil
+}
+
+func ValidateTokenDecimal(chain consensus.ChainContext, copyState *state.StateDB, tokenAddr common.Address, contractABI *abi.ABI) error {
+ result, err := RunContract(chain, copyState, tokenAddr, contractABI, getDecimalFunction)
+ if err != nil || result == nil {
+ return fmt.Errorf("cannot get token decimal. Token: %s . Err: %v", tokenAddr.Hex(), err)
+ }
+ return nil
+}
diff --git a/core/tx_journal.go b/core/tx_journal.go
index e872d7b530..a6e525012f 100644
--- a/core/tx_journal.go
+++ b/core/tx_journal.go
@@ -21,10 +21,10 @@ import (
"io"
"os"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
// errNoActiveJournal is returned if a transaction is attempted to be inserted
diff --git a/core/tx_list.go b/core/tx_list.go
index 31dcb37766..523d24430b 100644
--- a/core/tx_list.go
+++ b/core/tx_list.go
@@ -22,9 +22,9 @@ import (
"math/big"
"sort"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
@@ -302,8 +302,8 @@ func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[co
removed := l.txs.Filter(func(tx *types.Transaction) bool {
maximum := costLimit
if tx.To() != nil {
- if balance, ok := trc21Issuers[*tx.To()]; ok {
- maximum = balance
+ if feeCapacity, ok := trc21Issuers[*tx.To()]; ok {
+ return new(big.Int).Add(costLimit, feeCapacity).Cmp(tx.TRC21Cost()) < 0 || tx.Gas() > gasLimit
}
}
return tx.Cost().Cmp(maximum) > 0 || tx.Gas() > gasLimit
diff --git a/core/tx_list_test.go b/core/tx_list_test.go
index d579f501af..f0ec8eb8b4 100644
--- a/core/tx_list_test.go
+++ b/core/tx_list_test.go
@@ -20,8 +20,8 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
// Tests that transactions can be added to strict lists and list contents and
diff --git a/core/tx_pool.go b/core/tx_pool.go
index 5fc0b9257c..abb55e4948 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -25,13 +25,15 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/metrics"
+ "github.com/XinFinOrg/XDPoSChain/params"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
@@ -127,8 +129,19 @@ type blockChain interface {
CurrentBlock() *types.Block
GetBlock(hash common.Hash, number uint64) *types.Block
StateAt(root common.Hash) (*state.StateDB, error)
-
SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
+
+ // Engine retrieves the chain's consensus engine.
+ Engine() consensus.Engine
+
+ // GetHeader returns the hash corresponding to their hash.
+ GetHeader(common.Hash, uint64) *types.Header
+
+ // CurrentHeader retrieves the current header from the local chain.
+ CurrentHeader() *types.Header
+
+ // Config retrieves the blockchain's chain configuration.
+ Config() *params.ChainConfig
}
// TxPoolConfig are the configuration parameters of the transaction pool.
@@ -620,9 +633,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
balance := pool.currentState.GetBalance(from)
cost := tx.Cost()
minGasPrice := common.MinGasPrice
+ feeCapacity := big.NewInt(0)
+
if tx.To() != nil {
if value, ok := pool.trc21FeeCapacity[*tx.To()]; ok {
- balance = value
+ feeCapacity = value
if !state.ValidateTRC21Tx(pool.pendingState.StateDB, from, *tx.To(), tx.Data()) {
return ErrInsufficientFunds
}
@@ -630,7 +645,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
minGasPrice = common.TRC21GasPrice
}
}
- if balance.Cmp(cost) < 0 {
+ if new(big.Int).Add(balance, feeCapacity).Cmp(cost) < 0 {
return ErrInsufficientFunds
}
@@ -655,11 +670,24 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
}
}
- minGasDeploySMC := new(big.Int).Mul(new(big.Int).SetUint64(10), new(big.Int).SetUint64(params.Ether))
- if tx.To() == nil && (tx.Cost().Cmp(minGasDeploySMC) < 0 || tx.GasPrice().Cmp(new(big.Int).SetUint64(10000*params.Shannon)) < 0) {
- return ErrMinDeploySMC
+ /*
+ minGasDeploySMC := new(big.Int).Mul(new(big.Int).SetUint64(10), new(big.Int).SetUint64(params.Ether))
+ if tx.To() == nil && (tx.Cost().Cmp(minGasDeploySMC) < 0 || tx.GasPrice().Cmp(new(big.Int).SetUint64(10000*params.Shannon)) < 0) {
+ return ErrMinDeploySMC
+ }
+ */
+
+ // validate minFee slot for XDCZ
+ if tx.IsXDCZApplyTransaction() {
+ copyState := pool.currentState.Copy()
+ return ValidateXDCZApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:]))
}
+ // validate balance slot, token decimal for XDCX
+ if tx.IsXDCXApplyTransaction() {
+ copyState := pool.currentState.Copy()
+ return ValidateXDCXApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:]))
+ }
return nil
}
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index e1d3685919..9d3337d95f 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -19,6 +19,8 @@ package core
import (
"crypto/ecdsa"
"fmt"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"io/ioutil"
"math/big"
"math/rand"
@@ -26,13 +28,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/event"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// testTxPoolConfig is a transaction pool configuration without stateful disk
@@ -50,6 +51,22 @@ type testBlockChain struct {
chainHeadFeed *event.Feed
}
+func (bc *testBlockChain) Engine() consensus.Engine {
+ return nil
+}
+
+func (bc *testBlockChain) GetHeader(common.Hash, uint64) *types.Header {
+ return nil
+}
+
+func (bc *testBlockChain) CurrentHeader() *types.Header {
+ return nil
+}
+
+func (bc *testBlockChain) Config() *params.ChainConfig {
+ return nil
+}
+
func (bc *testBlockChain) CurrentBlock() *types.Block {
return types.NewBlock(&types.Header{
GasLimit: bc.gasLimit,
@@ -78,7 +95,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
}
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
- diskdb, _ := ethdb.NewMemDatabase()
+ diskdb := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(diskdb))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -158,7 +175,7 @@ func (c *testChain) State() (*state.StateDB, error) {
// a state change between those fetches.
stdb := c.statedb
if *c.trigger {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
// simulate that the new head block included tx0 and tx1
c.statedb.SetNonce(c.address, 2)
@@ -175,7 +192,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
t.Parallel()
var (
- db, _ = ethdb.NewMemDatabase()
+ db = rawdb.NewMemoryDatabase()
key, _ = crypto.GenerateKey()
address = crypto.PubkeyToAddress(key.PublicKey)
statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
@@ -337,7 +354,7 @@ func TestTransactionChainFork(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey)
resetState := func() {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
statedb.AddBalance(addr, big.NewInt(100000000000000))
@@ -367,7 +384,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey)
resetState := func() {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
statedb.AddBalance(addr, big.NewInt(100000000000000))
@@ -558,7 +575,7 @@ func TestTransactionPostponing(t *testing.T) {
t.Parallel()
// Create the pool to test the postponing with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -774,7 +791,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
t.Parallel()
// Create the pool to test the limit enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -855,8 +872,10 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
//
// This logic should not hold for local transactions, unless the local tracking
// mechanism is disabled.
-func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
-func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) }
+func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
+func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
+ testTransactionQueueTimeLimiting(t, true)
+}
func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
common.MinGasPrice = big.NewInt(0)
@@ -865,7 +884,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
evictionInterval = time.Second
// Create the pool to test the non-expiration enforcement
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -964,8 +983,10 @@ func TestTransactionPendingLimiting(t *testing.T) {
// Tests that the transaction limits are enforced the same way irrelevant whether
// the transactions are added one by one or in batches.
-func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
-func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) }
+func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
+func TestTransactionPendingLimitingEquivalency(t *testing.T) {
+ testTransactionLimitingEquivalency(t, 0)
+}
func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
t.Parallel()
@@ -1020,7 +1041,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1067,7 +1088,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1102,7 +1123,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1152,7 +1173,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1274,7 +1295,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1337,7 +1358,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1439,7 +1460,7 @@ func TestTransactionReplacement(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1534,7 +1555,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
os.Remove(journal)
// Create the original pool to inject transaction into the journal
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
@@ -1633,7 +1654,7 @@ func TestTransactionStatusCheck(t *testing.T) {
t.Parallel()
// Create the pool to test the status retrievals with
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
diff --git a/core/types.go b/core/types.go
index dc10406f09..5cf4e31148 100644
--- a/core/types.go
+++ b/core/types.go
@@ -17,11 +17,14 @@
package core
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
"math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
)
// Validator is an interface which defines the standard for block validation. It
@@ -35,6 +38,10 @@ type Validator interface {
// ValidateState validates the given statedb and optionally the receipts and
// gas used.
ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error
+
+ ValidateTradingOrder(statedb *state.StateDB, XDCxStatedb *tradingstate.TradingStateDB, txMatchBatch tradingstate.TxMatchBatch, coinbase common.Address, header *types.Header) error
+
+ ValidateLendingOrder(statedb *state.StateDB, lendingStateDb *lendingstate.LendingStateDB, XDCxStatedb *tradingstate.TradingStateDB, batch lendingstate.TxLendingBatch, coinbase common.Address, header *types.Header) error
}
// Processor is an interface for processing blocks using a given initial state.
@@ -44,6 +51,6 @@ type Validator interface {
// of gas used in the process and return an error if any of the internal rules
// failed.
type Processor interface {
- Process(block *types.Block, statedb *state.StateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
- ProcessBlockNoValidator(block *CalculatedBlock, statedb *state.StateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
+ Process(block *types.Block, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
+ ProcessBlockNoValidator(block *CalculatedBlock, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
}
diff --git a/core/types/block.go b/core/types/block.go
index 87d989b69c..cbeb565373 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -27,10 +27,10 @@ import (
"time"
"unsafe"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
var (
diff --git a/core/types/block_test.go b/core/types/block_test.go
index b12c8fddcf..c95aaae717 100644
--- a/core/types/block_test.go
+++ b/core/types/block_test.go
@@ -21,8 +21,8 @@ import (
"testing"
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
"reflect"
)
diff --git a/core/types/bloom9.go b/core/types/bloom9.go
index a76b6f33c5..94b05cd178 100644
--- a/core/types/bloom9.go
+++ b/core/types/bloom9.go
@@ -20,8 +20,8 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
type bytesBacked interface {
diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go
index a28ac0e7af..3cdb383262 100644
--- a/core/types/bloom9_test.go
+++ b/core/types/bloom9_test.go
@@ -54,7 +54,7 @@ func TestBloom(t *testing.T) {
import (
"testing"
- "github.com/ethereum/go-ethereum/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
)
func TestBloom9(t *testing.T) {
diff --git a/core/types/derive_sha.go b/core/types/derive_sha.go
index 00c42c5bc6..92ce133113 100644
--- a/core/types/derive_sha.go
+++ b/core/types/derive_sha.go
@@ -19,9 +19,9 @@ package types
import (
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+ "github.com/XinFinOrg/XDPoSChain/trie"
)
type DerivableList interface {
diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go
index 1b92cd9cf4..dc48332426 100644
--- a/core/types/gen_header_json.go
+++ b/core/types/gen_header_json.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
var _ = (*headerMarshaling)(nil)
diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go
index 1b5ae3c653..cb0071938d 100644
--- a/core/types/gen_log_json.go
+++ b/core/types/gen_log_json.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"errors"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
var _ = (*logMarshaling)(nil)
diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go
index c297adebb6..5fce768227 100644
--- a/core/types/gen_receipt_json.go
+++ b/core/types/gen_receipt_json.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"errors"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
var _ = (*receiptMarshaling)(nil)
diff --git a/core/types/gen_tx_json.go b/core/types/gen_tx_json.go
index c27da67096..11b6f8ab41 100644
--- a/core/types/gen_tx_json.go
+++ b/core/types/gen_tx_json.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
)
var _ = (*txdataMarshaling)(nil)
diff --git a/core/types/lending_signing.go b/core/types/lending_signing.go
new file mode 100644
index 0000000000..6aaaedb481
--- /dev/null
+++ b/core/types/lending_signing.go
@@ -0,0 +1,233 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package types
+
+import (
+ "crypto/ecdsa"
+ "fmt"
+ "math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/log"
+)
+
+// LendingSigner interface for lending signer transaction
+type LendingSigner interface {
+ // Sender returns the sender address of the transaction.
+ Sender(tx *LendingTransaction) (common.Address, error)
+ // SignatureValues returns the raw R, S, V values corresponding to the
+ // given signature.
+ SignatureValues(tx *LendingTransaction, sig []byte) (r, s, v *big.Int, err error)
+ // Hash returns the hash to be signed.
+ Hash(tx *LendingTransaction) common.Hash
+ // Equal returns true if the given signer is the same as the receiver.
+ Equal(LendingSigner) bool
+}
+
+type lendingsigCache struct {
+ signer LendingSigner
+ from common.Address
+}
+
+// LendingSender returns the address derived from the signature (V, R, S) using secp256k1
+// elliptic curve and an error if it failed deriving or upon an incorrect
+// signature.
+//
+// Sender may cache the address, allowing it to be used regardless of
+// signing method. The cache is invalidated if the cached signer does
+// not match the signer used in the current call.
+func LendingSender(signer LendingSigner, tx *LendingTransaction) (common.Address, error) {
+ if sc := tx.from.Load(); sc != nil {
+ sigCache := sc.(lendingsigCache)
+ // If the signer used to derive from in a previous
+ // call is not the same as used current, invalidate
+ // the cache.
+ if sigCache.signer.Equal(signer) {
+ return sigCache.from, nil
+ }
+ }
+
+ addr, err := signer.Sender(tx)
+ if err != nil {
+ return common.Address{}, err
+ }
+ tx.from.Store(lendingsigCache{signer: signer, from: addr})
+ return addr, nil
+}
+
+// LendingSignTx signs the lending transaction using the given lending signer and private key
+func LendingSignTx(tx *LendingTransaction, s LendingSigner, prv *ecdsa.PrivateKey) (*LendingTransaction, error) {
+ h := s.Hash(tx)
+ message := crypto.Keccak256(
+ []byte("\x19Ethereum Signed Message:\n32"),
+ h.Bytes(),
+ )
+
+ sig, err := crypto.Sign(message[:], prv)
+ if err != nil {
+ return nil, err
+ }
+ return tx.WithSignature(s, sig)
+}
+
+//LendingTxSigner signer
+type LendingTxSigner struct{}
+
+// Equal compare two signer
+func (lendingsign LendingTxSigner) Equal(s2 LendingSigner) bool {
+ _, ok := s2.(LendingSigner)
+ return ok
+}
+
+//SignatureValues returns signature values. This signature needs to be in the [R || S || V] format where V is 0 or 1.
+func (lendingsign LendingTxSigner) SignatureValues(tx *LendingTransaction, sig []byte) (r, s, v *big.Int, err error) {
+ if len(sig) != 65 {
+ panic(fmt.Sprintf("wrong size for signature: got %d, want 65", len(sig)))
+ }
+ r = new(big.Int).SetBytes(sig[:32])
+ s = new(big.Int).SetBytes(sig[32:64])
+ v = new(big.Int).SetBytes([]byte{sig[64] + 27})
+ return r, s, v, nil
+}
+
+// LendingCreateHash hash of new lending transaction
+func (lendingsign LendingTxSigner) LendingCreateHash(tx *LendingTransaction) common.Hash {
+ log.Debug("LendingCreateHash", "relayer", tx.RelayerAddress().Hex(), "useraddress", tx.UserAddress().Hex(),
+ "collateral", tx.CollateralToken().Hex(), "lending", tx.LendingToken().Hex(), "quantity", tx.Quantity(), "term", tx.Term(),
+ "interest", tx.Interest(), "side", tx.Side, "status", tx.Status(), "type", tx.Type(), "nonce", tx.Nonce())
+ borrowing := tx.Side() == LendingSideBorrow
+ sha := sha3.NewKeccak256()
+ sha.Write(tx.RelayerAddress().Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ if borrowing {
+ sha.Write(tx.CollateralToken().Bytes())
+ }
+ sha.Write(tx.LendingToken().Bytes())
+ sha.Write(common.BigToHash(tx.Quantity()).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Term()))).Bytes())
+ if tx.IsLoTypeLending() {
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Interest()))).Bytes())
+ }
+ sha.Write([]byte(tx.Side()))
+ sha.Write([]byte(tx.Status()))
+ sha.Write([]byte(tx.Type()))
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ if borrowing {
+ autoTopUp := int64(0)
+ if tx.AutoTopUp() {
+ autoTopUp = int64(1)
+ }
+ sha.Write(common.BigToHash(big.NewInt(autoTopUp)).Bytes())
+ }
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// LendingCancelHash hash of cancelled lending transaction
+func (lendingsign LendingTxSigner) LendingCancelHash(tx *LendingTransaction) common.Hash {
+ sha := sha3.NewKeccak256()
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ sha.Write([]byte(tx.Status()))
+ sha.Write(tx.RelayerAddress().Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ sha.Write(tx.LendingToken().Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Term()))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.LendingId()))).Bytes())
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// LendingRepayHash hash of cancelled lending transaction
+func (lendingsign LendingTxSigner) LendingRepayHash(tx *LendingTransaction) common.Hash {
+ sha := sha3.NewKeccak256()
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ sha.Write([]byte(tx.Status()))
+ sha.Write(tx.RelayerAddress().Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ sha.Write(tx.LendingToken().Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Term()))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.LendingTradeId()))).Bytes())
+ sha.Write([]byte(tx.Type()))
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// LendingTopUpHash hash of cancelled lending transaction
+func (lendingsign LendingTxSigner) LendingTopUpHash(tx *LendingTransaction) common.Hash {
+ sha := sha3.NewKeccak256()
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ sha.Write([]byte(tx.Status()))
+ sha.Write(tx.RelayerAddress().Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ sha.Write(tx.LendingToken().Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Term()))).Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.LendingTradeId()))).Bytes())
+ sha.Write(common.BigToHash(tx.Quantity()).Bytes())
+ sha.Write([]byte(tx.Type()))
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// Hash returns the hash to be signed by the sender.
+// It does not uniquely identify the transaction.
+func (lendingsign LendingTxSigner) Hash(tx *LendingTransaction) common.Hash {
+ if tx.IsCancelledLending() {
+ return lendingsign.LendingCancelHash(tx)
+ }
+ if tx.IsCreatedLending() {
+ return lendingsign.LendingCreateHash(tx)
+ }
+ if tx.IsTopupLending() {
+ return lendingsign.LendingTopUpHash(tx)
+ }
+ if tx.IsRepayLending() {
+ return lendingsign.LendingRepayHash(tx)
+ }
+ return common.Hash{}
+}
+
+// Sender get signer from
+func (lendingsign LendingTxSigner) Sender(tx *LendingTransaction) (common.Address, error) {
+
+ message := crypto.Keccak256(
+ []byte("\x19Ethereum Signed Message:\n32"),
+ lendingsign.Hash(tx).Bytes(),
+ )
+ V, R, S := tx.Signature()
+
+ sigBytes, err := MarshalSignature(R, S, V)
+ if err != nil {
+ return common.Address{}, err
+ }
+ pubKey, err := crypto.SigToPub(message, sigBytes)
+ if err != nil {
+ return common.Address{}, err
+ }
+ address := crypto.PubkeyToAddress(*pubKey)
+ return address, nil
+
+}
+
+// CacheLendingSigner cache signed lending transaction
+func CacheLendingSigner(signer LendingSigner, tx *LendingTransaction) {
+ if tx == nil {
+ return
+ }
+ addr, err := signer.Sender(tx)
+ if err != nil {
+ return
+ }
+ tx.from.Store(lendingsigCache{signer: signer, from: addr})
+}
diff --git a/core/types/lending_transaction.go b/core/types/lending_transaction.go
new file mode 100644
index 0000000000..806c44d546
--- /dev/null
+++ b/core/types/lending_transaction.go
@@ -0,0 +1,420 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package types
+
+import (
+ "container/heap"
+ "errors"
+ "io"
+ "math/big"
+ "sync/atomic"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+)
+
+//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
+
+var (
+ // ErrInvalidLengdingSig invalidate signer
+ ErrInvalidLengdingSig = errors.New("invalid transaction v, r, s values")
+ errNoSignerLengding = errors.New("missing signing methods")
+)
+
+const (
+ LendingStatusNew = "NEW"
+ LendingStatusOpen = "OPEN"
+ LendingStatusPartialFilled = "PARTIAL_FILLED"
+ LendingStatusFilled = "FILLED"
+ LendingStatusCancelled = "CANCELLED"
+ LendingTypeMo = "MO"
+ LendingTypeLo = "LO"
+ LendingSideBorrow = "BORROW"
+ LendingSideInvest = "INVEST"
+ LendingRePay = "REPAY"
+ LendingTopup = "TOPUP"
+)
+
+// LendingTransaction lending transaction
+type LendingTransaction struct {
+ data lendingtxdata
+ // caches
+ hash atomic.Value
+ size atomic.Value
+ from atomic.Value
+}
+
+type lendingtxdata struct {
+ AccountNonce uint64 `json:"nonce" gencodec:"required"`
+ Quantity *big.Int `json:"quantity,omitempty"`
+ Interest uint64 `json:"interest"`
+ RelayerAddress common.Address `json:"relayerAddress,omitempty"`
+ UserAddress common.Address `json:"userAddress,omitempty"`
+ CollateralToken common.Address `json:"collateralToken,omitempty"`
+ AutoTopUp bool `json:"autoTopUp,omitempty"`
+ LendingToken common.Address `json:"lendingToken,omitempty"`
+ Term uint64 `json:"term"`
+ Status string `json:"status,omitempty"`
+ Side string `json:"side,omitempty"`
+ Type string `json:"type,omitempty"`
+ LendingId uint64 `json:"lendingId,omitempty"`
+ LendingTradeId uint64 `json:"tradeId,omitempty"`
+ ExtraData string `json:"extraData,omitempty"`
+
+ // Signature values
+ V *big.Int `json:"v" gencodec:"required"`
+ R *big.Int `json:"r" gencodec:"required"`
+ S *big.Int `json:"s" gencodec:"required"`
+
+ // This is only used when marshaling to JSON.
+ Hash common.Hash `json:"hash"`
+}
+
+// IsCreatedLending check if tx is cancelled transaction
+func (tx *LendingTransaction) IsCreatedLending() bool {
+ if (tx.IsLoTypeLending() || tx.IsMoTypeLending()) && tx.Status() == LendingStatusNew {
+ return true
+ }
+ return false
+}
+
+// IsCancelledLending check if tx is cancelled transaction
+func (tx *LendingTransaction) IsCancelledLending() bool {
+ if tx.Status() == LendingStatusCancelled {
+ return true
+ }
+ return false
+}
+
+// IsRepayLending check if tx is repay lending transaction
+func (tx *LendingTransaction) IsRepayLending() bool {
+ if tx.Type() == LendingRePay {
+ return true
+ }
+ return false
+}
+
+// IsTopupLending check if tx is repay lending transaction
+func (tx *LendingTransaction) IsTopupLending() bool {
+ if tx.Type() == LendingTopup {
+ return true
+ }
+ return false
+}
+
+// IsMoTypeLending check if tx type is MO lending
+func (tx *LendingTransaction) IsMoTypeLending() bool {
+ if tx.Type() == LendingTypeMo {
+ return true
+ }
+ return false
+}
+
+// IsLoTypeLending check if tx type is LO lending
+func (tx *LendingTransaction) IsLoTypeLending() bool {
+ if tx.Type() == LendingTypeLo {
+ return true
+ }
+ return false
+}
+
+// EncodeRLP implements rlp.Encoder
+func (tx *LendingTransaction) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, &tx.data)
+}
+
+// DecodeRLP implements rlp.Decoder
+func (tx *LendingTransaction) DecodeRLP(s *rlp.Stream) error {
+ _, size, _ := s.Kind()
+ err := s.Decode(&tx.data)
+ if err == nil {
+ tx.size.Store(common.StorageSize(rlp.ListSize(size)))
+ }
+
+ return err
+}
+
+// Nonce return nonce of account
+func (tx *LendingTransaction) Nonce() uint64 { return tx.data.AccountNonce }
+
+// Quantity return quantity of transaction
+func (tx *LendingTransaction) Quantity() *big.Int { return tx.data.Quantity }
+
+// RelayerAddress return relayer address transaction
+func (tx *LendingTransaction) RelayerAddress() common.Address { return tx.data.RelayerAddress }
+
+// UserAddress return user address transaction
+func (tx *LendingTransaction) UserAddress() common.Address { return tx.data.UserAddress }
+
+// Interest return interest percent of transaction
+func (tx *LendingTransaction) Interest() uint64 { return tx.data.Interest }
+
+// Duration return period of transaction
+func (tx *LendingTransaction) Duration() uint64 { return tx.data.Term }
+
+// Term return period of transaction
+func (tx *LendingTransaction) Term() uint64 { return tx.data.Term }
+
+// CollateralToken return collateral token address
+func (tx *LendingTransaction) CollateralToken() common.Address { return tx.data.CollateralToken }
+
+// CollateralToken return autoTopUp flag
+func (tx *LendingTransaction) AutoTopUp() bool { return tx.data.AutoTopUp }
+
+// LendingToken return lending token address of transaction
+func (tx *LendingTransaction) LendingToken() common.Address { return tx.data.LendingToken }
+
+// Status return status of lending transaction
+func (tx *LendingTransaction) Status() string { return tx.data.Status }
+
+// Side return side of lending transaction
+func (tx *LendingTransaction) Side() string { return tx.data.Side }
+
+// Type return type of lending transaction
+func (tx *LendingTransaction) Type() string { return tx.data.Type }
+
+// Type return extraData of lending transaction
+func (tx *LendingTransaction) ExtraData() string { return tx.data.ExtraData }
+
+// Signature return signature of lending transaction
+func (tx *LendingTransaction) Signature() (V, R, S *big.Int) { return tx.data.V, tx.data.R, tx.data.S }
+
+// LendingHash return hash of lending transaction
+func (tx *LendingTransaction) LendingHash() common.Hash { return tx.data.Hash }
+
+// LendingId return lending id
+func (tx *LendingTransaction) LendingId() uint64 { return tx.data.LendingId }
+
+// LendingId return lendingTradeId
+func (tx *LendingTransaction) LendingTradeId() uint64 { return tx.data.LendingTradeId }
+
+// SetLendingHash set hash of lending transaction hash
+func (tx *LendingTransaction) SetLendingHash(h common.Hash) { tx.data.Hash = h }
+
+// From get transaction from
+func (tx *LendingTransaction) From() *common.Address {
+ if tx.data.V != nil {
+ signer := LendingTxSigner{}
+ if f, err := LendingSender(signer, tx); err != nil {
+ return nil
+ } else {
+ return &f
+ }
+
+ }
+ return nil
+
+}
+
+// WithSignature returns a new transaction with the given signature.
+// This signature needs to be formatted as described in the yellow paper (v+27).
+func (tx *LendingTransaction) WithSignature(signer LendingSigner, sig []byte) (*LendingTransaction, error) {
+ r, s, v, err := signer.SignatureValues(tx, sig)
+ if err != nil {
+ return nil, err
+ }
+ cpy := &LendingTransaction{data: tx.data}
+ cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
+ return cpy, nil
+}
+
+// ImportSignature make lending tx with specific signature
+func (tx *LendingTransaction) ImportSignature(V, R, S *big.Int) *LendingTransaction {
+
+ if V != nil {
+ tx.data.V = V
+ }
+ if R != nil {
+ tx.data.R = R
+ }
+ if S != nil {
+ tx.data.S = S
+ }
+ return tx
+}
+
+// Hash hashes the RLP encoding of tx.
+// It uniquely identifies the transaction.
+func (tx *LendingTransaction) Hash() common.Hash {
+ if hash := tx.hash.Load(); hash != nil {
+ return hash.(common.Hash)
+ }
+ v := rlpHash(tx)
+ tx.hash.Store(v)
+ return v
+}
+
+// CacheHash cache hash
+func (tx *LendingTransaction) CacheHash() {
+ v := rlpHash(tx)
+ tx.hash.Store(v)
+}
+
+// Size returns the true RLP encoded storage size of the transaction, either by
+// encoding and returning it, or returning a previsouly cached value.
+func (tx *LendingTransaction) Size() common.StorageSize {
+ if size := tx.size.Load(); size != nil {
+ return size.(common.StorageSize)
+ }
+ c := writeCounter(0)
+ rlp.Encode(&c, &tx.data)
+ tx.size.Store(common.StorageSize(c))
+ return common.StorageSize(c)
+}
+
+// NewLendingTransaction init lending from value
+func NewLendingTransaction(nonce uint64, quantity *big.Int, interest, duration uint64, relayerAddress, userAddress, lendingToken, collateralToken common.Address, autoTopUp bool, status, side, typeLending string, hash common.Hash, id, tradeId uint64, extraData string) *LendingTransaction {
+ return newLendingTransaction(nonce, quantity, interest, duration, relayerAddress, userAddress, lendingToken, collateralToken, autoTopUp, status, side, typeLending, hash, id, tradeId, extraData)
+}
+
+func newLendingTransaction(nonce uint64, quantity *big.Int, interest, duration uint64, relayerAddress, userAddress, lendingToken, collateralToken common.Address, autoTopUp bool, status, side, typeLending string, hash common.Hash, id, tradeId uint64, extraData string) *LendingTransaction {
+ d := lendingtxdata{
+ AccountNonce: nonce,
+ Quantity: new(big.Int),
+ Interest: interest,
+ Term: duration,
+ RelayerAddress: relayerAddress,
+ UserAddress: userAddress,
+ LendingToken: lendingToken,
+ CollateralToken: collateralToken,
+ AutoTopUp: autoTopUp,
+ Status: status,
+ Side: side,
+ Type: typeLending,
+ Hash: hash,
+ LendingId: id,
+ LendingTradeId: tradeId,
+ ExtraData: extraData,
+ V: new(big.Int),
+ R: new(big.Int),
+ S: new(big.Int),
+ }
+ if quantity != nil {
+ d.Quantity.Set(quantity)
+ }
+
+ return &LendingTransaction{data: d}
+}
+
+// LendingTransactions is a Transaction slice type for basic sorting.
+type LendingTransactions []*LendingTransaction
+
+// Len returns the length of s.
+func (s LendingTransactions) Len() int { return len(s) }
+
+// Swap swaps the i'th and the j'th element in s.
+func (s LendingTransactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// GetRlp implements Rlpable and returns the i'th element of s in rlp.
+func (s LendingTransactions) GetRlp(i int) []byte {
+ enc, _ := rlp.EncodeToBytes(s[i])
+ return enc
+}
+
+// LendingTxDifference returns a new set t which is the difference between a to b.
+func LendingTxDifference(a, b LendingTransactions) (keep LendingTransactions) {
+ keep = make(LendingTransactions, 0, len(a))
+
+ remove := make(map[common.Hash]struct{})
+ for _, tx := range b {
+ remove[tx.Hash()] = struct{}{}
+ }
+
+ for _, tx := range a {
+ if _, ok := remove[tx.Hash()]; !ok {
+ keep = append(keep, tx)
+ }
+ }
+
+ return keep
+}
+
+// LendingTxByNonce sorted lending by nonce defined
+type LendingTxByNonce LendingTransactions
+
+func (s LendingTxByNonce) Len() int { return len(s) }
+func (s LendingTxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce }
+
+func (s LendingTxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func (s *LendingTxByNonce) Push(x interface{}) {
+ *s = append(*s, x.(*LendingTransaction))
+}
+
+func (s *LendingTxByNonce) Pop() interface{} {
+ old := *s
+ n := len(old)
+ x := old[n-1]
+ *s = old[0 : n-1]
+ return x
+}
+
+//LendingTransactionByNonce sort transaction by nonce
+type LendingTransactionByNonce struct {
+ txs map[common.Address]LendingTransactions
+ heads LendingTxByNonce
+ signer LendingSigner
+}
+
+// NewLendingTransactionByNonce sort transaction by nonce
+func NewLendingTransactionByNonce(signer LendingSigner, txs map[common.Address]LendingTransactions) *LendingTransactionByNonce {
+ // Initialize a price based heap with the head transactions
+ heads := make(LendingTxByNonce, 0, len(txs))
+ for from, accTxs := range txs {
+ heads = append(heads, accTxs[0])
+ // Ensure the sender address is from the signer
+ acc, _ := LendingSender(signer, accTxs[0])
+ txs[acc] = accTxs[1:]
+ if from != acc {
+ delete(txs, from)
+ }
+ }
+ heap.Init(&heads)
+
+ // Assemble and return the transaction set
+ return &LendingTransactionByNonce{
+ txs: txs,
+ heads: heads,
+ signer: signer,
+ }
+}
+
+// Peek returns the next transaction by price.
+func (t *LendingTransactionByNonce) Peek() *LendingTransaction {
+ if len(t.heads) == 0 {
+ return nil
+ }
+ return t.heads[0]
+}
+
+// Shift replaces the current best head with the next one from the same account.
+func (t *LendingTransactionByNonce) Shift() {
+ acc, _ := LendingSender(t.signer, t.heads[0])
+ if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
+ t.heads[0], t.txs[acc] = txs[0], txs[1:]
+ heap.Fix(&t.heads, 0)
+ } else {
+ heap.Pop(&t.heads)
+ }
+}
+
+// Pop removes the best transaction, *not* replacing it with the next one from
+// the same account. This should be used when a transaction cannot be executed
+// and hence all subsequent ones should be discarded from the same account.
+func (t *LendingTransactionByNonce) Pop() {
+ heap.Pop(&t.heads)
+}
diff --git a/core/types/log.go b/core/types/log.go
index be5de38da7..d459d2892f 100644
--- a/core/types/log.go
+++ b/core/types/log.go
@@ -20,9 +20,9 @@ import (
"fmt"
"io"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
//go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go
diff --git a/core/types/log_test.go b/core/types/log_test.go
index 0e56acfe4a..b6ab7810b7 100644
--- a/core/types/log_test.go
+++ b/core/types/log_test.go
@@ -22,9 +22,9 @@ import (
"reflect"
"testing"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
)
var unmarshalLogTests = map[string]struct {
diff --git a/core/types/order_signing.go b/core/types/order_signing.go
new file mode 100644
index 0000000000..50f5591f3b
--- /dev/null
+++ b/core/types/order_signing.go
@@ -0,0 +1,205 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package types
+
+import (
+ "crypto/ecdsa"
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+)
+
+// OrderSigner interface for order transaction
+type OrderSigner interface {
+ // Sender returns the sender address of the transaction.
+ Sender(tx *OrderTransaction) (common.Address, error)
+ // SignatureValues returns the raw R, S, V values corresponding to the
+ // given signature.
+ SignatureValues(tx *OrderTransaction, sig []byte) (r, s, v *big.Int, err error)
+ // Hash returns the hash to be signed.
+ Hash(tx *OrderTransaction) common.Hash
+ // Equal returns true if the given signer is the same as the receiver.
+ Equal(OrderSigner) bool
+}
+
+type ordersigCache struct {
+ signer OrderSigner
+ from common.Address
+}
+
+// OrderSender returns the address derived from the signature (V, R, S) using secp256k1
+// elliptic curve and an error if it failed deriving or upon an incorrect
+// signature.
+//
+// Sender may cache the address, allowing it to be used regardless of
+// signing method. The cache is invalidated if the cached signer does
+// not match the signer used in the current call.
+func OrderSender(signer OrderSigner, tx *OrderTransaction) (common.Address, error) {
+ if sc := tx.from.Load(); sc != nil {
+ sigCache := sc.(ordersigCache)
+ // If the signer used to derive from in a previous
+ // call is not the same as used current, invalidate
+ // the cache.
+ if sigCache.signer.Equal(signer) {
+ return sigCache.from, nil
+ }
+ }
+
+ addr, err := signer.Sender(tx)
+ if err != nil {
+ return common.Address{}, err
+ }
+ tx.from.Store(ordersigCache{signer: signer, from: addr})
+ return addr, nil
+}
+
+// OrderSignTx signs the order transaction using the given order signer and private key
+func OrderSignTx(tx *OrderTransaction, s OrderSigner, prv *ecdsa.PrivateKey) (*OrderTransaction, error) {
+ h := s.Hash(tx)
+ message := crypto.Keccak256(
+ []byte("\x19Ethereum Signed Message:\n32"),
+ h.Bytes(),
+ )
+
+ sig, err := crypto.Sign(message[:], prv)
+ if err != nil {
+ return nil, err
+ }
+ return tx.WithSignature(s, sig)
+}
+
+//OrderTxSigner signer
+type OrderTxSigner struct{}
+
+// Equal compare two signer
+func (ordersign OrderTxSigner) Equal(s2 OrderSigner) bool {
+ _, ok := s2.(OrderSigner)
+ return ok
+}
+
+//SignatureValues returns signature values. This signature needs to be in the [R || S || V] format where V is 0 or 1.
+func (ordersign OrderTxSigner) SignatureValues(tx *OrderTransaction, sig []byte) (r, s, v *big.Int, err error) {
+ if len(sig) != 65 {
+ panic(fmt.Sprintf("wrong size for signature: got %d, want 65", len(sig)))
+ }
+ r = new(big.Int).SetBytes(sig[:32])
+ s = new(big.Int).SetBytes(sig[32:64])
+ v = new(big.Int).SetBytes([]byte{sig[64] + 27})
+ return r, s, v, nil
+}
+
+// OrderCreateHash hash of new order
+func (ordersign OrderTxSigner) OrderCreateHash(tx *OrderTransaction) common.Hash {
+ sha := sha3.NewKeccak256()
+ sha.Write(tx.ExchangeAddress().Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ sha.Write(tx.BaseToken().Bytes())
+ sha.Write(tx.QuoteToken().Bytes())
+ sha.Write(common.BigToHash(tx.Quantity()).Bytes())
+ if tx.IsLoTypeOrder() {
+ if tx.Price() != nil {
+ sha.Write(common.BigToHash(tx.Price()).Bytes())
+ }
+ }
+ sha.Write(common.BigToHash(tx.EncodedSide()).Bytes())
+ sha.Write([]byte(tx.Status()))
+ sha.Write([]byte(tx.Type()))
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// OrderCancelHash hash of cancelled order
+func (ordersign OrderTxSigner) OrderCancelHash(tx *OrderTransaction) common.Hash {
+ sha := sha3.NewKeccak256()
+ sha.Write(tx.OrderHash().Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.Nonce()))).Bytes())
+ sha.Write(tx.UserAddress().Bytes())
+ sha.Write(common.BigToHash(big.NewInt(int64(tx.OrderID()))).Bytes())
+ sha.Write([]byte(tx.Status()))
+ sha.Write(tx.ExchangeAddress().Bytes())
+ sha.Write(tx.BaseToken().Bytes())
+ sha.Write(tx.QuoteToken().Bytes())
+
+ return common.BytesToHash(sha.Sum(nil))
+}
+
+// Hash returns the hash to be signed by the sender.
+// It does not uniquely identify the transaction.
+func (ordersign OrderTxSigner) Hash(tx *OrderTransaction) common.Hash {
+ if tx.IsCancelledOrder() {
+ return ordersign.OrderCancelHash(tx)
+ }
+ return ordersign.OrderCreateHash(tx)
+}
+
+//MarshalSignature encode signature
+func MarshalSignature(R, S, V *big.Int) ([]byte, error) {
+ sigBytes1 := common.BigToHash(R).Bytes()
+ sigBytes2 := common.BigToHash(S).Bytes()
+ v := big.NewInt(0)
+ v.Sub(V, big.NewInt(27))
+
+ bigstr := v.String()
+ n, err := strconv.ParseInt(bigstr, 10, 8)
+ if err != nil {
+ return nil, err
+ }
+ sigBytes3 := byte(n)
+ sigBytes := append([]byte{}, sigBytes1...)
+ sigBytes = append(sigBytes, sigBytes2...)
+ sigBytes = append(sigBytes, sigBytes3)
+
+ return sigBytes, nil
+}
+
+// Sender get signer from
+func (ordersign OrderTxSigner) Sender(tx *OrderTransaction) (common.Address, error) {
+
+ message := crypto.Keccak256(
+ []byte("\x19Ethereum Signed Message:\n32"),
+ ordersign.Hash(tx).Bytes(),
+ )
+ V, R, S := tx.Signature()
+
+ sigBytes, err := MarshalSignature(R, S, V)
+ if err != nil {
+ return common.Address{}, err
+ }
+ pubKey, err := crypto.SigToPub(message, sigBytes)
+ if err != nil {
+ return common.Address{}, err
+ }
+ address := crypto.PubkeyToAddress(*pubKey)
+ return address, nil
+
+}
+
+// CacheOrderSigner cache signed order
+func CacheOrderSigner(signer OrderSigner, tx *OrderTransaction) {
+ if tx == nil {
+ return
+ }
+ addr, err := signer.Sender(tx)
+ if err != nil {
+ return
+ }
+ tx.from.Store(ordersigCache{signer: signer, from: addr})
+}
diff --git a/core/types/order_transaction.go b/core/types/order_transaction.go
new file mode 100644
index 0000000000..c064444d7f
--- /dev/null
+++ b/core/types/order_transaction.go
@@ -0,0 +1,349 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package types
+
+import (
+ "container/heap"
+ "errors"
+ "io"
+ "math/big"
+ "sync/atomic"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
+)
+
+//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
+
+var (
+ // ErrInvalidOrderSig invalidate signer
+ ErrInvalidOrderSig = errors.New("invalid transaction v, r, s values")
+ errNoSignerOrder = errors.New("missing signing methods")
+)
+
+const (
+ OrderStatusNew = "NEW"
+ OrderStatusOpen = "OPEN"
+ OrderStatusPartialFilled = "PARTIAL_FILLED"
+ OrderStatusFilled = "FILLED"
+ OrderStatusCancelled = "CANCELLED"
+ OrderTypeMo = "MO"
+ OrderTypeLo = "LO"
+)
+
+// OrderTransaction order transaction
+type OrderTransaction struct {
+ data ordertxdata
+ // caches
+ hash atomic.Value
+ size atomic.Value
+ from atomic.Value
+}
+
+type ordertxdata struct {
+ AccountNonce uint64 `json:"nonce" gencodec:"required"`
+ Quantity *big.Int `json:"quantity,omitempty"`
+ Price *big.Int `json:"price,omitempty"`
+ ExchangeAddress common.Address `json:"exchangeAddress,omitempty"`
+ UserAddress common.Address `json:"userAddress,omitempty"`
+ BaseToken common.Address `json:"baseToken,omitempty"`
+ QuoteToken common.Address `json:"quoteToken,omitempty"`
+ Status string `json:"status,omitempty"`
+ Side string `json:"side,omitempty"`
+ Type string `json:"type,omitempty"`
+ OrderID uint64 `json:"orderid,omitempty"`
+ // Signature values
+ V *big.Int `json:"v" gencodec:"required"`
+ R *big.Int `json:"r" gencodec:"required"`
+ S *big.Int `json:"s" gencodec:"required"`
+
+ // This is only used when marshaling to JSON.
+ Hash common.Hash `json:"hash"`
+}
+
+// IsCancelledOrder check if tx is cancelled transaction
+func (tx *OrderTransaction) IsCancelledOrder() bool {
+ if tx.Status() == OrderStatusCancelled {
+ return true
+ }
+ return false
+}
+
+// IsMoTypeOrder check if tx type is MO Order
+func (tx *OrderTransaction) IsMoTypeOrder() bool {
+ if tx.Type() == OrderTypeMo {
+ return true
+ }
+ return false
+}
+
+// IsLoTypeOrder check if tx type is LO Order
+func (tx *OrderTransaction) IsLoTypeOrder() bool {
+ if tx.Type() == OrderTypeLo {
+ return true
+ }
+ return false
+}
+
+// EncodeRLP implements rlp.Encoder
+func (tx *OrderTransaction) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, &tx.data)
+}
+
+// DecodeRLP implements rlp.Decoder
+func (tx *OrderTransaction) DecodeRLP(s *rlp.Stream) error {
+ _, size, _ := s.Kind()
+ err := s.Decode(&tx.data)
+ if err == nil {
+ tx.size.Store(common.StorageSize(rlp.ListSize(size)))
+ }
+
+ return err
+}
+
+// Nonce return nonce of account
+func (tx *OrderTransaction) Nonce() uint64 { return tx.data.AccountNonce }
+func (tx *OrderTransaction) Quantity() *big.Int { return tx.data.Quantity }
+func (tx *OrderTransaction) Price() *big.Int { return tx.data.Price }
+func (tx *OrderTransaction) ExchangeAddress() common.Address { return tx.data.ExchangeAddress }
+func (tx *OrderTransaction) UserAddress() common.Address { return tx.data.UserAddress }
+func (tx *OrderTransaction) BaseToken() common.Address { return tx.data.BaseToken }
+func (tx *OrderTransaction) QuoteToken() common.Address { return tx.data.QuoteToken }
+func (tx *OrderTransaction) Status() string { return tx.data.Status }
+func (tx *OrderTransaction) Side() string { return tx.data.Side }
+func (tx *OrderTransaction) Type() string { return tx.data.Type }
+func (tx *OrderTransaction) Signature() (V, R, S *big.Int) { return tx.data.V, tx.data.R, tx.data.S }
+func (tx *OrderTransaction) OrderHash() common.Hash { return tx.data.Hash }
+func (tx *OrderTransaction) OrderID() uint64 { return tx.data.OrderID }
+func (tx *OrderTransaction) EncodedSide() *big.Int {
+ if tx.Side() == "BUY" {
+ return big.NewInt(0)
+ } else {
+ return big.NewInt(1)
+ }
+}
+func (tx *OrderTransaction) SetOrderHash(h common.Hash) { tx.data.Hash = h }
+
+// From get transaction from
+func (tx *OrderTransaction) From() *common.Address {
+ if tx.data.V != nil {
+ signer := OrderTxSigner{}
+ if f, err := OrderSender(signer, tx); err != nil {
+ return nil
+ } else {
+ return &f
+ }
+ } else {
+ return nil
+ }
+}
+
+// WithSignature returns a new transaction with the given signature.
+// This signature needs to be formatted as described in the yellow paper (v+27).
+func (tx *OrderTransaction) WithSignature(signer OrderSigner, sig []byte) (*OrderTransaction, error) {
+ r, s, v, err := signer.SignatureValues(tx, sig)
+ if err != nil {
+ return nil, err
+ }
+ cpy := &OrderTransaction{data: tx.data}
+ cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
+ return cpy, nil
+}
+
+// ImportSignature make order tx with specific signature
+func (tx *OrderTransaction) ImportSignature(V, R, S *big.Int) *OrderTransaction {
+
+ if V != nil {
+ tx.data.V = V
+ }
+ if R != nil {
+ tx.data.R = R
+ }
+ if S != nil {
+ tx.data.S = S
+ }
+ return tx
+}
+
+// Hash hashes the RLP encoding of tx.
+// It uniquely identifies the transaction.
+func (tx *OrderTransaction) Hash() common.Hash {
+ if hash := tx.hash.Load(); hash != nil {
+ return hash.(common.Hash)
+ }
+ v := rlpHash(tx)
+ tx.hash.Store(v)
+ return v
+}
+
+// CacheHash cache hash
+func (tx *OrderTransaction) CacheHash() {
+ v := rlpHash(tx)
+ tx.hash.Store(v)
+}
+
+// Size returns the true RLP encoded storage size of the transaction, either by
+// encoding and returning it, or returning a previsouly cached value.
+func (tx *OrderTransaction) Size() common.StorageSize {
+ if size := tx.size.Load(); size != nil {
+ return size.(common.StorageSize)
+ }
+ c := writeCounter(0)
+ rlp.Encode(&c, &tx.data)
+ tx.size.Store(common.StorageSize(c))
+ return common.StorageSize(c)
+}
+
+// NewOrderTransaction init order from value
+func NewOrderTransaction(nonce uint64, quantity, price *big.Int, ex, ua, b, q common.Address, status, side, t string, hash common.Hash, id uint64) *OrderTransaction {
+ return newOrderTransaction(nonce, quantity, price, ex, ua, b, q, status, side, t, hash, id)
+}
+
+func newOrderTransaction(nonce uint64, quantity, price *big.Int, ex, ua, b, q common.Address, status, side, t string, hash common.Hash, id uint64) *OrderTransaction {
+ d := ordertxdata{
+ AccountNonce: nonce,
+ Quantity: new(big.Int),
+ Price: new(big.Int),
+ ExchangeAddress: ex,
+ UserAddress: ua,
+ BaseToken: b,
+ QuoteToken: q,
+ Status: status,
+ Side: side,
+ Type: t,
+ Hash: hash,
+ OrderID: id,
+ V: new(big.Int),
+ R: new(big.Int),
+ S: new(big.Int),
+ }
+ if quantity != nil {
+ d.Quantity.Set(quantity)
+ }
+ if price != nil {
+ d.Price.Set(price)
+ }
+
+ return &OrderTransaction{data: d}
+}
+
+// OrderTransactions is a Transaction slice type for basic sorting.
+type OrderTransactions []*OrderTransaction
+
+// Len returns the length of s.
+func (s OrderTransactions) Len() int { return len(s) }
+
+// Swap swaps the i'th and the j'th element in s.
+func (s OrderTransactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// GetRlp implements Rlpable and returns the i'th element of s in rlp.
+func (s OrderTransactions) GetRlp(i int) []byte {
+ enc, _ := rlp.EncodeToBytes(s[i])
+ return enc
+}
+
+// OrderTxDifference returns a new set t which is the difference between a to b.
+func OrderTxDifference(a, b OrderTransactions) (keep OrderTransactions) {
+ keep = make(OrderTransactions, 0, len(a))
+
+ remove := make(map[common.Hash]struct{})
+ for _, tx := range b {
+ remove[tx.Hash()] = struct{}{}
+ }
+
+ for _, tx := range a {
+ if _, ok := remove[tx.Hash()]; !ok {
+ keep = append(keep, tx)
+ }
+ }
+
+ return keep
+}
+
+// OrderTxByNonce sorted order by nonce defined
+type OrderTxByNonce OrderTransactions
+
+func (s OrderTxByNonce) Len() int { return len(s) }
+func (s OrderTxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce }
+
+func (s OrderTxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func (s *OrderTxByNonce) Push(x interface{}) {
+ *s = append(*s, x.(*OrderTransaction))
+}
+
+func (s *OrderTxByNonce) Pop() interface{} {
+ old := *s
+ n := len(old)
+ x := old[n-1]
+ *s = old[0 : n-1]
+ return x
+}
+
+type OrderTransactionByNonce struct {
+ txs map[common.Address]OrderTransactions
+ heads OrderTxByNonce
+ signer OrderSigner
+}
+
+func NewOrderTransactionByNonce(signer OrderSigner, txs map[common.Address]OrderTransactions) *OrderTransactionByNonce {
+ // Initialize a price based heap with the head transactions
+ heads := make(OrderTxByNonce, 0, len(txs))
+ for from, accTxs := range txs {
+ heads = append(heads, accTxs[0])
+ // Ensure the sender address is from the signer
+ acc, _ := OrderSender(signer, accTxs[0])
+ txs[acc] = accTxs[1:]
+ if from != acc {
+ delete(txs, from)
+ }
+ }
+ heap.Init(&heads)
+
+ // Assemble and return the transaction set
+ return &OrderTransactionByNonce{
+ txs: txs,
+ heads: heads,
+ signer: signer,
+ }
+}
+
+// Peek returns the next transaction by price.
+func (t *OrderTransactionByNonce) Peek() *OrderTransaction {
+ if len(t.heads) == 0 {
+ return nil
+ }
+ return t.heads[0]
+}
+
+// Shift replaces the current best head with the next one from the same account.
+func (t *OrderTransactionByNonce) Shift() {
+ acc, _ := OrderSender(t.signer, t.heads[0])
+ if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
+ t.heads[0], t.txs[acc] = txs[0], txs[1:]
+ heap.Fix(&t.heads, 0)
+ } else {
+ heap.Pop(&t.heads)
+ }
+}
+
+// Pop removes the best transaction, *not* replacing it with the next one from
+// the same account. This should be used when a transaction cannot be executed
+// and hence all subsequent ones should be discarded from the same account.
+func (t *OrderTransactionByNonce) Pop() {
+ heap.Pop(&t.heads)
+}
diff --git a/core/types/receipt.go b/core/types/receipt.go
index f945f6f6a2..f49d6f1c87 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -22,9 +22,9 @@ import (
"io"
"unsafe"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
diff --git a/core/types/transaction.go b/core/types/transaction.go
index cbcb9a4db3..e551d23796 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -17,6 +17,7 @@
package types
import (
+ "bytes"
"container/heap"
"errors"
"fmt"
@@ -24,17 +25,23 @@ import (
"math/big"
"sync/atomic"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
var (
- ErrInvalidSig = errors.New("invalid transaction v, r, s values")
- errNoSigner = errors.New("missing signing methods")
+ ErrInvalidSig = errors.New("invalid transaction v, r, s values")
+ errNoSigner = errors.New("missing signing methods")
+ skipNonceDestinationAddress = map[string]bool{
+ common.XDCXAddr: true,
+ common.TradingStateAddr: true,
+ common.XDCXLendingAddress: true,
+ common.XDCXLendingFinalizedTradeAddress: true,
+ }
)
// deriveSigner makes a *best* guess about which signer to use.
@@ -298,7 +305,54 @@ func (tx *Transaction) IsSpecialTransaction() bool {
if tx.To() == nil {
return false
}
- return tx.To().String() == common.RandomizeSMC || tx.To().String() == common.BlockSigners
+ toBytes := tx.To().Bytes()
+ randomizeSMCBytes := common.HexToAddress(common.RandomizeSMC).Bytes()
+ blockSignersBytes := common.HexToAddress(common.BlockSigners).Bytes()
+ return bytes.Equal(toBytes, randomizeSMCBytes) || bytes.Equal(toBytes, blockSignersBytes)
+}
+
+func (tx *Transaction) IsTradingTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+
+ if tx.To().String() != common.XDCXAddr {
+ return false
+ }
+
+ return true
+}
+
+func (tx *Transaction) IsLendingTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+
+ if tx.To().String() != common.XDCXLendingAddress {
+ return false
+ }
+ return true
+}
+
+func (tx *Transaction) IsLendingFinalizedTradeTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+
+ if tx.To().String() != common.XDCXLendingFinalizedTradeAddress {
+ return false
+ }
+ return true
+}
+
+func (tx *Transaction) IsSkipNonceTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+ if skip := skipNonceDestinationAddress[tx.To().String()]; skip {
+ return true
+ }
+ return false
}
func (tx *Transaction) IsSigningTransaction() bool {
@@ -361,6 +415,60 @@ func (tx *Transaction) IsVotingTransaction() (bool, *common.Address) {
return b, nil
}
+func (tx *Transaction) IsXDCXApplyTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+
+ addr := common.XDCXListingSMC
+ if common.IsTestnet {
+ addr = common.XDCXListingSMCTestNet
+ }
+ if tx.To().String() != addr.String() {
+ return false
+ }
+
+ method := common.ToHex(tx.Data()[0:4])
+
+ if method != common.XDCXApplyMethod {
+ return false
+ }
+
+ // 4 bytes for function name
+ // 32 bytes for 1 parameter
+ if len(tx.Data()) != (32 + 4) {
+ return false
+ }
+ return true
+}
+
+func (tx *Transaction) IsXDCZApplyTransaction() bool {
+ if tx.To() == nil {
+ return false
+ }
+
+ addr := common.TRC21IssuerSMC
+ if common.IsTestnet {
+ addr = common.TRC21IssuerSMCTestNet
+ }
+ if tx.To().String() != addr.String() {
+ return false
+ }
+
+ method := common.ToHex(tx.Data()[0:4])
+ if method != common.XDCZApplyMethod {
+ return false
+ }
+
+ // 4 bytes for function name
+ // 32 bytes for 1 parameter
+ if len(tx.Data()) != (32 + 4) {
+ return false
+ }
+
+ return true
+}
+
func (tx *Transaction) String() string {
var from, to string
if tx.data.V != nil {
diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go
index 512b02b122..3658ed43b9 100644
--- a/core/types/transaction_signing.go
+++ b/core/types/transaction_signing.go
@@ -22,9 +22,9 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
var (
diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go
index 689fc38a9b..90c6e90682 100644
--- a/core/types/transaction_signing_test.go
+++ b/core/types/transaction_signing_test.go
@@ -20,9 +20,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
func TestEIP155Signing(t *testing.T) {
diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go
index 055320dda6..234ef322c5 100644
--- a/core/types/transaction_test.go
+++ b/core/types/transaction_test.go
@@ -23,9 +23,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
// The values in those tests are from the Transaction Tests
diff --git a/core/vm/XDCx_price.go b/core/vm/XDCx_price.go
new file mode 100644
index 0000000000..c5ffd81191
--- /dev/null
+++ b/core/vm/XDCx_price.go
@@ -0,0 +1,71 @@
+package vm
+
+import (
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
+ "github.com/XinFinOrg/XDPoSChain/params"
+)
+
+const XDCXPriceNumberOfBytesReturn = 32
+
+// XDCxPrice implements a pre-compile contract to get token price in XDCx
+
+type XDCxLastPrice struct {
+ tradingStateDB *tradingstate.TradingStateDB
+}
+type XDCxEpochPrice struct {
+ tradingStateDB *tradingstate.TradingStateDB
+}
+
+func (t *XDCxLastPrice) RequiredGas(input []byte) uint64 {
+ return params.XDCXPriceGas
+}
+
+func (t *XDCxLastPrice) Run(input []byte) ([]byte, error) {
+ // input includes baseTokenAddress, quoteTokenAddress
+ if t.tradingStateDB != nil && len(input) == 64 {
+ base := common.BytesToAddress(input[12:32]) // 20 bytes from 13-32
+ quote := common.BytesToAddress(input[44:]) // 20 bytes from 45-64
+ price := t.tradingStateDB.GetLastPrice(tradingstate.GetTradingOrderBookHash(base, quote))
+ if price != nil {
+ log.Debug("Run GetLastPrice", "base", base.Hex(), "quote", quote.Hex(), "price", price)
+ return common.LeftPadBytes(price.Bytes(), XDCXPriceNumberOfBytesReturn), nil
+ }
+ }
+ return common.LeftPadBytes([]byte{}, XDCXPriceNumberOfBytesReturn), nil
+}
+
+func (t *XDCxLastPrice) SetTradingState(tradingStateDB *tradingstate.TradingStateDB) {
+ if tradingStateDB != nil {
+ t.tradingStateDB = tradingStateDB.Copy()
+ } else {
+ t.tradingStateDB = nil
+ }
+}
+
+func (t *XDCxEpochPrice) RequiredGas(input []byte) uint64 {
+ return params.XDCXPriceGas
+}
+
+func (t *XDCxEpochPrice) Run(input []byte) ([]byte, error) {
+ // input includes baseTokenAddress, quoteTokenAddress
+ if t.tradingStateDB != nil && len(input) == 64 {
+ base := common.BytesToAddress(input[12:32]) // 20 bytes from 13-32
+ quote := common.BytesToAddress(input[44:]) // 20 bytes from 45-64
+ price := t.tradingStateDB.GetMediumPriceBeforeEpoch(tradingstate.GetTradingOrderBookHash(base, quote))
+ if price != nil {
+ log.Debug("Run GetEpochPrice", "base", base.Hex(), "quote", quote.Hex(), "price", price)
+ return common.LeftPadBytes(price.Bytes(), XDCXPriceNumberOfBytesReturn), nil
+ }
+ }
+ return common.LeftPadBytes([]byte{}, XDCXPriceNumberOfBytesReturn), nil
+}
+
+func (t *XDCxEpochPrice) SetTradingState(tradingStateDB *tradingstate.TradingStateDB) {
+ if tradingStateDB != nil {
+ t.tradingStateDB = tradingStateDB.Copy()
+ } else {
+ t.tradingStateDB = nil
+ }
+}
diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index f9c4298d39..449cded2a8 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -16,45 +16,49 @@
package vm
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
+const (
+ set2BitsMask = uint16(0b1100_0000_0000_0000)
+ set3BitsMask = uint16(0b1110_0000_0000_0000)
+ set4BitsMask = uint16(0b1111_0000_0000_0000)
+ set5BitsMask = uint16(0b1111_1000_0000_0000)
+ set6BitsMask = uint16(0b1111_1100_0000_0000)
+ set7BitsMask = uint16(0b1111_1110_0000_0000)
)
-// destinations stores one map per contract (keyed by hash of code).
-// The maps contain an entry for each location of a JUMPDEST
-// instruction.
-type destinations map[common.Hash]bitvec
-
-// has checks whether code has a JUMPDEST at dest.
-func (d destinations) has(codehash common.Hash, code []byte, dest *big.Int) bool {
- // PC cannot go beyond len(code) and certainly can't be bigger than 63bits.
- // Don't bother checking for JUMPDEST in that case.
- udest := dest.Uint64()
- if dest.BitLen() >= 63 || udest >= uint64(len(code)) {
- return false
- }
-
- m, analysed := d[codehash]
- if !analysed {
- m = codeBitmap(code)
- d[codehash] = m
- }
- return OpCode(code[udest]) == JUMPDEST && m.codeSegment(udest)
-}
-
// bitvec is a bit vector which maps bytes in a program.
// An unset bit means the byte is an opcode, a set bit means
// it's data (i.e. argument of PUSHxx).
type bitvec []byte
-func (bits *bitvec) set(pos uint64) {
- (*bits)[pos/8] |= 0x80 >> (pos % 8)
+var lookup = [8]byte{
+ 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1,
}
-func (bits *bitvec) set8(pos uint64) {
- (*bits)[pos/8] |= 0xFF >> (pos % 8)
- (*bits)[pos/8+1] |= ^(0xFF >> (pos % 8))
+
+func (bits bitvec) set1(pos uint64) {
+ bits[pos/8] |= lookup[pos%8]
+}
+
+func (bits bitvec) setN(flag uint16, pos uint64) {
+ a := flag >> (pos % 8)
+ bits[pos/8] |= byte(a >> 8)
+ if b := byte(a); b != 0 {
+ // If the bit-setting affects the neighbouring byte, we can assign - no need to OR it,
+ // since it's the first write to that byte
+ bits[pos/8+1] = b
+ }
+}
+
+func (bits bitvec) set8(pos uint64) {
+ a := byte(0xFF >> (pos % 8))
+ bits[pos/8] |= a
+ bits[pos/8+1] = ^a
+}
+
+func (bits bitvec) set16(pos uint64) {
+ a := byte(0xFF >> (pos % 8))
+ bits[pos/8] |= a
+ bits[pos/8+1] = 0xFF
+ bits[pos/8+2] = ^a
}
// codeSegment checks if the position is in a code segment.
@@ -68,22 +72,52 @@ func codeBitmap(code []byte) bitvec {
// ends with a PUSH32, the algorithm will push zeroes onto the
// bitvector outside the bounds of the actual code.
bits := make(bitvec, len(code)/8+1+4)
+ return codeBitmapInternal(code, bits)
+}
+
+// codeBitmapInternal is the internal implementation of codeBitmap.
+// It exists for the purpose of being able to run benchmark tests
+// without dynamic allocations affecting the results.
+func codeBitmapInternal(code, bits bitvec) bitvec {
for pc := uint64(0); pc < uint64(len(code)); {
op := OpCode(code[pc])
-
- if op >= PUSH1 && op <= PUSH32 {
- numbits := op - PUSH1 + 1
- pc++
+ pc++
+ if op < PUSH1 || op > PUSH32 {
+ continue
+ }
+ numbits := op - PUSH1 + 1
+ if numbits >= 8 {
+ for ; numbits >= 16; numbits -= 16 {
+ bits.set16(pc)
+ pc += 16
+ }
for ; numbits >= 8; numbits -= 8 {
- bits.set8(pc) // 8
+ bits.set8(pc)
pc += 8
}
- for ; numbits > 0; numbits-- {
- bits.set(pc)
- pc++
- }
- } else {
- pc++
+ }
+ switch numbits {
+ case 1:
+ bits.set1(pc)
+ pc += 1
+ case 2:
+ bits.setN(set2BitsMask, pc)
+ pc += 2
+ case 3:
+ bits.setN(set3BitsMask, pc)
+ pc += 3
+ case 4:
+ bits.setN(set4BitsMask, pc)
+ pc += 4
+ case 5:
+ bits.setN(set5BitsMask, pc)
+ pc += 5
+ case 6:
+ bits.setN(set6BitsMask, pc)
+ pc += 6
+ case 7:
+ bits.setN(set7BitsMask, pc)
+ pc += 7
}
}
return bits
diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go
index a64f90ed9c..99e4e386b4 100644
--- a/core/vm/analysis_test.go
+++ b/core/vm/analysis_test.go
@@ -16,7 +16,11 @@
package vm
-import "testing"
+import (
+ "testing"
+
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+)
func TestJumpDestAnalysis(t *testing.T) {
tests := []struct {
@@ -43,11 +47,49 @@ func TestJumpDestAnalysis(t *testing.T) {
{[]byte{byte(PUSH32)}, 0xFF, 1},
{[]byte{byte(PUSH32)}, 0xFF, 2},
}
- for _, test := range tests {
+ for i, test := range tests {
ret := codeBitmap(test.code)
if ret[test.which] != test.exp {
- t.Fatalf("expected %x, got %02x", test.exp, ret[test.which])
+ t.Fatalf("test %d: expected %x, got %02x", i, test.exp, ret[test.which])
}
}
-
+}
+
+func BenchmarkJumpdestAnalysis_1200k(bench *testing.B) {
+ // 1.4 ms
+ code := make([]byte, 1200000)
+ bench.ResetTimer()
+ for i := 0; i < bench.N; i++ {
+ codeBitmap(code)
+ }
+ bench.StopTimer()
+}
+func BenchmarkJumpdestHashing_1200k(bench *testing.B) {
+ // 4 ms
+ code := make([]byte, 1200000)
+ bench.ResetTimer()
+ for i := 0; i < bench.N; i++ {
+ crypto.Keccak256Hash(code)
+ }
+ bench.StopTimer()
+}
+
+func BenchmarkJumpdestOpAnalysis(bench *testing.B) {
+ var op OpCode
+ bencher := func(b *testing.B) {
+ code := make([]byte, 32*b.N)
+ for i := range code {
+ code[i] = byte(op)
+ }
+ bits := make(bitvec, len(code)/8+1+4)
+ b.ResetTimer()
+ codeBitmapInternal(code, bits)
+ }
+ for op = PUSH1; op <= PUSH32; op++ {
+ bench.Run(op.String(), bencher)
+ }
+ op = JUMPDEST
+ bench.Run(op.String(), bencher)
+ op = STOP
+ bench.Run(op.String(), bencher)
}
diff --git a/core/vm/common.go b/core/vm/common.go
index 17de38decb..194e3897f8 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -19,17 +19,35 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
-// calculates the memory size required for a step
-func calcMemSize(off, l *big.Int) *big.Int {
- if l.Sign() == 0 {
- return common.Big0
+// calcMemSize64 calculates the required memory size, and returns
+// the size and whether the result overflowed uint64
+func calcMemSize64(off, l *big.Int) (uint64, bool) {
+ if !l.IsUint64() {
+ return 0, true
}
+ return calcMemSize64WithUint(off, l.Uint64())
+}
- return new(big.Int).Add(off, l)
+// calcMemSize64WithUint calculates the required memory size, and returns
+// the size and whether the result overflowed uint64
+// Identical to calcMemSize64, but length is a uint64
+func calcMemSize64WithUint(off *big.Int, length64 uint64) (uint64, bool) {
+ // if length is zero, memsize is always zero, regardless of offset
+ if length64 == 0 {
+ return 0, false
+ }
+ // Check that offset doesn't overflow
+ if !off.IsUint64() {
+ return 0, true
+ }
+ offset64 := off.Uint64()
+ val := offset64 + length64
+ // if value < either of it's parts, then it overflowed
+ return val, val < offset64
}
// getData returns a slice from the data based on the start and size and pads
@@ -59,7 +77,7 @@ func getDataBig(data []byte, start *big.Int, size *big.Int) []byte {
// bigUint64 returns the integer casted to a uint64 and returns whether it
// overflowed in the process.
func bigUint64(v *big.Int) (uint64, bool) {
- return v.Uint64(), v.BitLen() > 64
+ return v.Uint64(), !v.IsUint64()
}
// toWordSize returns the ceiled word size required for memory expansion.
diff --git a/core/vm/contract.go b/core/vm/contract.go
index 66748e8215..cc9d59cf2d 100644
--- a/core/vm/contract.go
+++ b/core/vm/contract.go
@@ -19,7 +19,7 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
// ContractRef is a reference to the contract's backing object
@@ -40,7 +40,7 @@ type AccountRef common.Address
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
// Contract represents an ethereum contract in the state database. It contains
-// the the contract code, calling arguments. Contract implements ContractRef
+// the contract code, calling arguments. Contract implements ContractRef
type Contract struct {
// CallerAddress is the result of the caller which initialised this
// contract. However when the "call method" is delegated this value
@@ -49,7 +49,8 @@ type Contract struct {
caller ContractRef
self ContractRef
- jumpdests destinations // result of JUMPDEST analysis.
+ jumpdests map[common.Hash]bitvec // Aggregated result of JUMPDEST analysis.
+ analysis bitvec // Locally cached result of JUMPDEST analysis
Code []byte
CodeHash common.Hash
@@ -58,21 +59,17 @@ type Contract struct {
Gas uint64
value *big.Int
-
- Args []byte
-
- DelegateCall bool
}
// NewContract returns a new contract environment for the execution of EVM.
func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract {
- c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
+ c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object}
if parent, ok := caller.(*Contract); ok {
// Reuse JUMPDEST analysis from parent context if available.
c.jumpdests = parent.jumpdests
} else {
- c.jumpdests = make(destinations)
+ c.jumpdests = make(map[common.Hash]bitvec)
}
// Gas should be a pointer so it can safely be reduced through the run
@@ -84,10 +81,45 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin
return c
}
+func (c *Contract) validJumpdest(dest *big.Int) bool {
+ udest := dest.Uint64()
+ // PC cannot go beyond len(code) and certainly can't be bigger than 63bits.
+ // Don't bother checking for JUMPDEST in that case.
+ if dest.BitLen() >= 63 || udest >= uint64(len(c.Code)) {
+ return false
+ }
+ // Only JUMPDESTs allowed for destinations
+ if OpCode(c.Code[udest]) != JUMPDEST {
+ return false
+ }
+ // Do we have it locally already?
+ if c.analysis != nil {
+ return c.analysis.codeSegment(udest)
+ }
+ // If we have the code hash (but no analysis), we should look into the
+ // parent analysis map and see if the analysis has been made previously
+ if c.CodeHash != (common.Hash{}) {
+ analysis, exist := c.jumpdests[c.CodeHash]
+ if !exist {
+ // Do the analysis and save in parent context
+ analysis = codeBitmap(c.Code)
+ c.jumpdests[c.CodeHash] = analysis
+ }
+ // Also stash it in current contract for faster access
+ c.analysis = analysis
+ return analysis.codeSegment(udest)
+ }
+ // We don't have the code hash, most likely a piece of initcode not already
+ // in state trie. In that case, we do an analysis, and save it locally, so
+ // we don't have to recalculate it for every JUMP instruction in the execution
+ // However, we don't save it within the parent context
+ c.analysis = codeBitmap(c.Code)
+ return c.analysis.codeSegment(udest)
+}
+
// AsDelegate sets the contract to be a delegate call and returns the current
// contract (for chaining calls)
func (c *Contract) AsDelegate() *Contract {
- c.DelegateCall = true
// NOTE: caller must, at all times be a contract. It should never happen
// that caller is something other than a Contract.
parent := c.caller.(*Contract)
@@ -133,21 +165,23 @@ func (c *Contract) Address() common.Address {
return c.self.Address()
}
-// Value returns the contracts value (sent to it from it's caller)
+// Value returns the contract's value (sent to it from it's caller)
func (c *Contract) Value() *big.Int {
return c.value
}
-// SetCode sets the code to the contract
-func (self *Contract) SetCode(hash common.Hash, code []byte) {
- self.Code = code
- self.CodeHash = hash
-}
-
// SetCallCode sets the code of the contract and address of the backing data
// object
-func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
- self.Code = code
- self.CodeHash = hash
- self.CodeAddr = addr
+func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
+ c.Code = code
+ c.CodeHash = hash
+ c.CodeAddr = addr
+}
+
+// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash.
+// In case hash is not provided, the jumpdest analysis will not be saved to the parent context
+func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) {
+ c.Code = codeAndHash.code
+ c.CodeHash = codeAndHash.hash
+ c.CodeAddr = addr
}
diff --git a/core/vm/contracts.go b/core/vm/contracts.go
index 237450ea96..e7a19a3b21 100644
--- a/core/vm/contracts.go
+++ b/core/vm/contracts.go
@@ -18,14 +18,20 @@ package vm
import (
"crypto/sha256"
+ "encoding/binary"
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/bn256"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/core/vm/privacy"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto/blake2b"
+ "github.com/XinFinOrg/XDPoSChain/crypto/bn256"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ //lint:ignore SA1019 Needed for precompile
"golang.org/x/crypto/ripemd160"
)
@@ -49,14 +55,36 @@ var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
// contracts used in the Byzantium release.
var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
- common.BytesToAddress([]byte{1}): &ecrecover{},
- common.BytesToAddress([]byte{2}): &sha256hash{},
- common.BytesToAddress([]byte{3}): &ripemd160hash{},
- common.BytesToAddress([]byte{4}): &dataCopy{},
- common.BytesToAddress([]byte{5}): &bigModExp{},
- common.BytesToAddress([]byte{6}): &bn256Add{},
- common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
- common.BytesToAddress([]byte{8}): &bn256Pairing{},
+ common.BytesToAddress([]byte{1}): &ecrecover{},
+ common.BytesToAddress([]byte{2}): &sha256hash{},
+ common.BytesToAddress([]byte{3}): &ripemd160hash{},
+ common.BytesToAddress([]byte{4}): &dataCopy{},
+ common.BytesToAddress([]byte{5}): &bigModExp{},
+ common.BytesToAddress([]byte{6}): &bn256AddByzantium{},
+ common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{},
+ common.BytesToAddress([]byte{8}): &bn256PairingByzantium{},
+ common.BytesToAddress([]byte{30}): &ringSignatureVerifier{},
+ common.BytesToAddress([]byte{40}): &bulletproofVerifier{},
+ common.BytesToAddress([]byte{41}): &XDCxLastPrice{},
+ common.BytesToAddress([]byte{42}): &XDCxEpochPrice{},
+}
+
+// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
+// contracts used in the Istanbul release.
+var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
+ common.BytesToAddress([]byte{1}): &ecrecover{},
+ common.BytesToAddress([]byte{2}): &sha256hash{},
+ common.BytesToAddress([]byte{3}): &ripemd160hash{},
+ common.BytesToAddress([]byte{4}): &dataCopy{},
+ common.BytesToAddress([]byte{5}): &bigModExp{},
+ common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
+ common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
+ common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
+ common.BytesToAddress([]byte{9}): &blake2F{},
+ common.BytesToAddress([]byte{30}): &ringSignatureVerifier{},
+ common.BytesToAddress([]byte{40}): &bulletproofVerifier{},
+ common.BytesToAddress([]byte{41}): &XDCxLastPrice{},
+ common.BytesToAddress([]byte{42}): &XDCxEpochPrice{},
}
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
@@ -90,8 +118,13 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) {
if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) {
return nil, nil
}
+ // We must make sure not to modify the 'input', so placing the 'v' along with
+ // the signature needs to be done on a new allocation
+ sig := make([]byte, 65)
+ copy(sig, input[64:128])
+ sig[64] = v
// v needs to be at the end for libsecp256k1
- pubKey, err := crypto.Ecrecover(input[:32], append(input[64:128], v))
+ pubKey, err := crypto.Ecrecover(input[:32], sig)
// make sure the public key is a valid one
if err != nil {
return nil, nil
@@ -116,7 +149,7 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) {
return h[:], nil
}
-// RIPMED160 implemented as a native contract.
+// RIPEMD160 implemented as a native contract.
type ripemd160hash struct{}
// RequiredGas returns the gas required to execute the pre-compiled contract.
@@ -271,15 +304,9 @@ func newTwistPoint(blob []byte) (*bn256.G2, error) {
return p, nil
}
-// bn256Add implements a native elliptic curve point addition.
-type bn256Add struct{}
-
-// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256Add) RequiredGas(input []byte) uint64 {
- return params.Bn256AddGas
-}
-
-func (c *bn256Add) Run(input []byte) ([]byte, error) {
+// runBn256Add implements the Bn256Add precompile, referenced by both
+// Byzantium and Istanbul operations.
+func runBn256Add(input []byte) ([]byte, error) {
x, err := newCurvePoint(getData(input, 0, 64))
if err != nil {
return nil, err
@@ -293,15 +320,35 @@ func (c *bn256Add) Run(input []byte) ([]byte, error) {
return res.Marshal(), nil
}
-// bn256ScalarMul implements a native elliptic curve scalar multiplication.
-type bn256ScalarMul struct{}
+// bn256Add implements a native elliptic curve point addition conforming to
+// Istanbul consensus rules.
+type bn256AddIstanbul struct{}
// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 {
- return params.Bn256ScalarMulGas
+func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256AddGasIstanbul
}
-func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) {
+func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256Add(input)
+}
+
+// bn256AddByzantium implements a native elliptic curve point addition
+// conforming to Byzantium consensus rules.
+type bn256AddByzantium struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256AddGasByzantium
+}
+
+func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256Add(input)
+}
+
+// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by
+// both Byzantium and Istanbul operations.
+func runBn256ScalarMul(input []byte) ([]byte, error) {
p, err := newCurvePoint(getData(input, 0, 64))
if err != nil {
return nil, err
@@ -311,6 +358,32 @@ func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) {
return res.Marshal(), nil
}
+// bn256ScalarMulIstanbul implements a native elliptic curve scalar
+// multiplication conforming to Istanbul consensus rules.
+type bn256ScalarMulIstanbul struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256ScalarMulGasIstanbul
+}
+
+func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256ScalarMul(input)
+}
+
+// bn256ScalarMulByzantium implements a native elliptic curve scalar
+// multiplication conforming to Byzantium consensus rules.
+type bn256ScalarMulByzantium struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256ScalarMulGasByzantium
+}
+
+func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256ScalarMul(input)
+}
+
var (
// true32Byte is returned if the bn256 pairing check succeeds.
true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
@@ -322,15 +395,9 @@ var (
errBadPairingInput = errors.New("bad elliptic curve pairing size")
)
-// bn256Pairing implements a pairing pre-compile for the bn256 curve
-type bn256Pairing struct{}
-
-// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256Pairing) RequiredGas(input []byte) uint64 {
- return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas
-}
-
-func (c *bn256Pairing) Run(input []byte) ([]byte, error) {
+// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
+// Byzantium and Istanbul operations.
+func runBn256Pairing(input []byte) ([]byte, error) {
// Handle some corner cases cheaply
if len(input)%192 > 0 {
return nil, errBadPairingInput
@@ -358,3 +425,127 @@ func (c *bn256Pairing) Run(input []byte) ([]byte, error) {
}
return false32Byte, nil
}
+
+type ringSignatureVerifier struct{}
+type bulletproofVerifier struct{}
+
+func (c *bulletproofVerifier) RequiredGas(input []byte) uint64 {
+ //the gas should depends on the ringsize
+ return 100000
+}
+
+func (c *ringSignatureVerifier) RequiredGas(input []byte) uint64 {
+ //the gas should depends on the ringsize
+ return 100000
+}
+
+func (c *ringSignatureVerifier) Run(proof []byte) ([]byte, error) {
+ der, err := privacy.Deserialize(proof)
+ if err != nil {
+ return []byte{}, errors.New("Fail to deserialize proof")
+ }
+ if !privacy.Verify(der, false) {
+ return []byte{}, errors.New("Fail to verify ring signature")
+ }
+ return []byte{}, nil
+}
+
+func (c *bulletproofVerifier) Run(proof []byte) ([]byte, error) {
+ mrp := new(privacy.MultiRangeProof)
+ if mrp.Deserialize(proof) != nil {
+ return []byte{}, errors.New("failed to deserialize bulletproofs")
+ }
+
+ if !privacy.MRPVerify(mrp) {
+ return []byte{}, errors.New("failed to verify bulletproof")
+ }
+ return []byte{}, nil
+}
+
+// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
+// conforming to Istanbul consensus rules.
+type bn256PairingIstanbul struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
+}
+
+func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256Pairing(input)
+}
+
+// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve
+// conforming to Byzantium consensus rules.
+type bn256PairingByzantium struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
+}
+
+func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256Pairing(input)
+}
+
+type blake2F struct{}
+
+func (c *blake2F) RequiredGas(input []byte) uint64 {
+ // If the input is malformed, we can't calculate the gas, return 0 and let the
+ // actual call choke and fault.
+ if len(input) != blake2FInputLength {
+ return 0
+ }
+ return uint64(binary.BigEndian.Uint32(input[0:4]))
+}
+
+const (
+ blake2FInputLength = 213
+ blake2FFinalBlockBytes = byte(1)
+ blake2FNonFinalBlockBytes = byte(0)
+)
+
+var (
+ errBlake2FInvalidInputLength = errors.New("invalid input length")
+ errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
+)
+
+func (c *blake2F) Run(input []byte) ([]byte, error) {
+ // Make sure the input is valid (correct length and final flag)
+ if len(input) != blake2FInputLength {
+ return nil, errBlake2FInvalidInputLength
+ }
+ if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes {
+ return nil, errBlake2FInvalidFinalFlag
+ }
+ // Parse the input into the Blake2b call parameters
+ var (
+ rounds = binary.BigEndian.Uint32(input[0:4])
+ final = (input[212] == blake2FFinalBlockBytes)
+
+ h [8]uint64
+ m [16]uint64
+ t [2]uint64
+ )
+ for i := 0; i < 8; i++ {
+ offset := 4 + i*8
+ h[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
+ }
+ for i := 0; i < 16; i++ {
+ offset := 68 + i*8
+ m[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
+ }
+ t[0] = binary.LittleEndian.Uint64(input[196:204])
+ t[1] = binary.LittleEndian.Uint64(input[204:212])
+
+ // Execute the compression function, extract and return the result
+ blake2b.F(&h, m, t, final, rounds)
+
+ output := make([]byte, 64)
+ for i := 0; i < 8; i++ {
+ offset := i * 8
+ binary.LittleEndian.PutUint64(output[offset:offset+8], h[i])
+ }
+ return output, nil
+
+}
diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go
index 96083337c9..497943d174 100644
--- a/core/vm/contracts_test.go
+++ b/core/vm/contracts_test.go
@@ -17,21 +17,41 @@
package vm
import (
+ "bytes"
"fmt"
"math/big"
+ "reflect"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
)
// precompiledTest defines the input/output pairs for precompiled contract tests.
type precompiledTest struct {
input, expected string
- gas uint64
name string
noBenchmark bool // Benchmark primarily the worst-cases
}
+var (
+ BTCAddress = "C2fa1BA90b15E3612E0067A0020192938784D9C5"
+ USDTAddress = "45c25041b8e6CBD5c963E7943007187C3673C7c9"
+ BTCUSDTLastPrice = big.NewInt(9000000000)
+ BTCUSDTEpochPrice = big.NewInt(8800000000)
+)
+
+// precompiledFailureTest defines the input/error pairs for precompiled
+// contract failure tests.
+type precompiledFailureTest struct {
+ input string
+ expectedError error
+ name string
+}
+
// modexpTests are the test and benchmark data for the modexp precompiled contract.
var modexpTests = []precompiledTest{
{
@@ -336,8 +356,133 @@ var bn256PairingTests = []precompiledTest{
},
}
+var XDCxLastPriceTests = []precompiledTest{
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 32), common.Hex2BytesFixed(USDTAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(BTCUSDTLastPrice.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 30), common.Hex2BytesFixed(USDTAddress, 30)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT_invalid_input_length",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(USDTAddress, 32), common.Hex2BytesFixed(BTCAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "USDTBTC",
+ },
+}
+
+var XDCxEpochPriceTests = []precompiledTest{
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 32), common.Hex2BytesFixed(USDTAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(BTCUSDTEpochPrice.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 30), common.Hex2BytesFixed(USDTAddress, 30)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT_invalid_input_length",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(USDTAddress, 32), common.Hex2BytesFixed(BTCAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "USDTBTC",
+ },
+}
+
+var XDCxLastPriceWithEmptyTradingStateTests = []precompiledTest{
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 32), common.Hex2BytesFixed(USDTAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 30), common.Hex2BytesFixed(USDTAddress, 30)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT_invalid_input_length",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(USDTAddress, 32), common.Hex2BytesFixed(BTCAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "USDTBTC",
+ },
+}
+
+var XDCxEpochPriceWithEmptyTradingStateTests = []precompiledTest{
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 32), common.Hex2BytesFixed(USDTAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(BTCAddress, 30), common.Hex2BytesFixed(USDTAddress, 30)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "BTCUSDT_invalid_input_length",
+ },
+ {
+ input: common.Bytes2Hex(append(common.Hex2BytesFixed(USDTAddress, 32), common.Hex2BytesFixed(BTCAddress, 32)...)),
+ expected: common.Bytes2Hex(common.LeftPadBytes(common.Big0.Bytes(), XDCXPriceNumberOfBytesReturn)),
+ name: "USDTBTC",
+ },
+}
+
+// EIP-152 test vectors
+var blake2FMalformedInputTests = []precompiledFailureTest{
+ {
+ input: "",
+ expectedError: errBlake2FInvalidInputLength,
+ name: "vector 0: empty input",
+ },
+ {
+ input: "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expectedError: errBlake2FInvalidInputLength,
+ name: "vector 1: less than 213 bytes input",
+ },
+ {
+ input: "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expectedError: errBlake2FInvalidInputLength,
+ name: "vector 2: more than 213 bytes input",
+ },
+ {
+ input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002",
+ expectedError: errBlake2FInvalidFinalFlag,
+ name: "vector 3: malformed final block indicator flag",
+ },
+}
+
+// EIP-152 test vectors
+var blake2FTests = []precompiledTest{
+ {
+ input: "0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expected: "08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b",
+ name: "vector 4",
+ },
+ { // https://tools.ietf.org/html/rfc7693#appendix-A
+ input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expected: "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923",
+ name: "vector 5",
+ },
+ {
+ input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000",
+ expected: "75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735",
+ name: "vector 6",
+ },
+ {
+ input: "0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expected: "b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421",
+ name: "vector 7",
+ },
+ {
+ input: "007A120048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
+ expected: "6d2ce9e534d50e18ff866ae92d70cceba79bbcd14c63819fe48752c8aca87a4bb7dcc230d22a4047f0486cfcfb50a17b24b2899eb8fca370f22240adb5170189",
+ name: "vector 8",
+ },
+}
+
func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
- p := PrecompiledContractsByzantium[common.HexToAddress(addr)]
+ p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
in := common.Hex2Bytes(test.input)
contract := NewContract(AccountRef(common.HexToAddress("1337")),
nil, new(big.Int), p.RequiredGas(in))
@@ -347,6 +492,89 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
} else if common.Bytes2Hex(res) != test.expected {
t.Errorf("Expected %v, got %v", test.expected, common.Bytes2Hex(res))
}
+ // Verify that the precompile did not touch the input buffer
+ exp := common.Hex2Bytes(test.input)
+ if !bytes.Equal(in, exp) {
+ t.Errorf("Precompiled %v modified input data", addr)
+ }
+ })
+}
+
+func testXDCxPrecompiled(addr string, test precompiledTest, t *testing.T) {
+ db := rawdb.NewMemoryDatabase()
+ stateCache := tradingstate.NewDatabase(db)
+ tradingStateDB, _ := tradingstate.New(common.Hash{}, stateCache)
+ tradingStateDB.SetLastPrice(tradingstate.GetTradingOrderBookHash(common.HexToAddress(BTCAddress), common.HexToAddress(USDTAddress)), BTCUSDTLastPrice)
+ tradingStateDB.SetMediumPriceBeforeEpoch(tradingstate.GetTradingOrderBookHash(common.HexToAddress(BTCAddress), common.HexToAddress(USDTAddress)), BTCUSDTEpochPrice)
+
+ evm := NewEVM(Context{BlockNumber: common.Big1}, nil, tradingStateDB, ¶ms.ChainConfig{ByzantiumBlock: common.Big0}, Config{})
+ contractAddr := common.HexToAddress(addr)
+ p := PrecompiledContractsByzantium[contractAddr]
+ in := common.Hex2Bytes(test.input)
+ contract := NewContract(AccountRef(common.HexToAddress("1337")),
+ nil, new(big.Int), p.RequiredGas(in))
+ contract.SetCallCode(&contractAddr, common.Hash{}, []byte{})
+ t.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) {
+ if res, err := run(evm, contract, in, false); err != nil {
+ t.Error(err)
+ } else if common.Bytes2Hex(res) != test.expected {
+ t.Errorf("Expected %v, got %v", test.expected, common.Bytes2Hex(res))
+ }
+ })
+}
+
+func testPrecompiledWithEmptyTradingState(addr string, test precompiledTest, t *testing.T) {
+ evm := NewEVM(Context{BlockNumber: common.Big1}, nil, nil, ¶ms.ChainConfig{ByzantiumBlock: common.Big0}, Config{})
+
+ contractAddr := common.HexToAddress(addr)
+ p := PrecompiledContractsByzantium[contractAddr]
+ in := common.Hex2Bytes(test.input)
+ contract := NewContract(AccountRef(common.HexToAddress("1337")),
+ nil, new(big.Int), p.RequiredGas(in))
+ contract.SetCallCode(&contractAddr, common.Hash{}, []byte{})
+ t.Run(fmt.Sprintf("testPrecompiledWithEmptyTradingState-%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) {
+ if res, err := run(evm, contract, in, false); err != nil {
+ t.Error(err)
+ } else if common.Bytes2Hex(res) != test.expected {
+ t.Errorf("Expected %v, got %v", test.expected, common.Bytes2Hex(res))
+ }
+ })
+}
+
+func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
+ p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
+ in := common.Hex2Bytes(test.input)
+ contract := NewContract(AccountRef(common.HexToAddress("1337")),
+ nil, new(big.Int), p.RequiredGas(in)-1)
+ t.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) {
+ _, err := RunPrecompiledContract(p, in, contract)
+ if err.Error() != "out of gas" {
+ t.Errorf("Expected error [out of gas], got [%v]", err)
+ }
+ // Verify that the precompile did not touch the input buffer
+ exp := common.Hex2Bytes(test.input)
+ if !bytes.Equal(in, exp) {
+ t.Errorf("Precompiled %v modified input data", addr)
+ }
+ })
+}
+
+func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing.T) {
+ p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
+ in := common.Hex2Bytes(test.input)
+ contract := NewContract(AccountRef(common.HexToAddress("31337")),
+ nil, new(big.Int), p.RequiredGas(in))
+
+ t.Run(test.name, func(t *testing.T) {
+ _, err := RunPrecompiledContract(p, in, contract)
+ if !reflect.DeepEqual(err, test.expectedError) {
+ t.Errorf("Expected error [%v], got [%v]", test.expectedError, err)
+ }
+ // Verify that the precompile did not touch the input buffer
+ exp := common.Hex2Bytes(test.input)
+ if !bytes.Equal(in, exp) {
+ t.Errorf("Precompiled %v modified input data", addr)
+ }
})
}
@@ -354,7 +582,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
if test.noBenchmark {
return
}
- p := PrecompiledContractsByzantium[common.HexToAddress(addr)]
+ p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
in := common.Hex2Bytes(test.input)
reqGas := p.RequiredGas(in)
contract := NewContract(AccountRef(common.HexToAddress("1337")),
@@ -454,6 +682,13 @@ func BenchmarkPrecompiledBn256Add(bench *testing.B) {
}
}
+// Tests OOG
+func TestPrecompiledModExpOOG(t *testing.T) {
+ for _, test := range modexpTests {
+ testPrecompiledOOG("05", test, t)
+ }
+}
+
// Tests the sample inputs from the elliptic curve scalar multiplication EIP 213.
func TestPrecompiledBn256ScalarMul(t *testing.T) {
for _, test := range bn256ScalarMulTests {
@@ -475,9 +710,106 @@ func TestPrecompiledBn256Pairing(t *testing.T) {
}
}
+// Tests GetXDCXLastPrice
+func TestPrecompiledXDCXLastPrice(t *testing.T) {
+ for _, test := range XDCxLastPriceTests {
+ testXDCxPrecompiled("29", test, t)
+ }
+}
+
+// Tests GetXDCXEpochPrice
+func TestPrecompiledXDCXEpochPrice(t *testing.T) {
+ for _, test := range XDCxEpochPriceTests {
+ testXDCxPrecompiled("2A", test, t)
+ }
+}
+
+// Tests GetXDCXLastPrice
+func TestPrecompiledXDCXLastPriceWithEmptyTradingState(t *testing.T) {
+ for _, test := range XDCxLastPriceWithEmptyTradingStateTests {
+ testPrecompiledWithEmptyTradingState("29", test, t)
+ }
+}
+
+// Tests GetXDCXEpochPrice
+func TestPrecompiledXDCXEpochPriceWithEmptyTradingState(t *testing.T) {
+ for _, test := range XDCxEpochPriceWithEmptyTradingStateTests {
+ testPrecompiledWithEmptyTradingState("2A", test, t)
+ }
+}
+
// Behcnmarks the sample inputs from the elliptic curve pairing check EIP 197.
func BenchmarkPrecompiledBn256Pairing(bench *testing.B) {
for _, test := range bn256PairingTests {
benchmarkPrecompiled("08", test, bench)
}
}
+func TestPrecompiledBlake2F(t *testing.T) {
+ for _, test := range blake2FTests {
+ testPrecompiled("09", test, t)
+ }
+}
+
+func BenchmarkPrecompiledBlake2F(bench *testing.B) {
+ for _, test := range blake2FTests {
+ benchmarkPrecompiled("09", test, bench)
+ }
+}
+
+func TestPrecompileBlake2FMalformedInput(t *testing.T) {
+ for _, test := range blake2FMalformedInputTests {
+ testPrecompiledFailure("09", test, t)
+ }
+}
+
+// EcRecover test vectors
+var ecRecoverTests = []precompiledTest{
+ {
+ input: "a8b53bdf3306a35a7103ab5504a0c9b492295564b6202b1942a84ef300107281" +
+ "000000000000000000000000000000000000000000000000000000000000001b" +
+ "3078356531653033663533636531386237373263636230303933666637316633" +
+ "6635336635633735623734646362333161383561613862383839326234653862" +
+ "1122334455667788991011121314151617181920212223242526272829303132",
+ expected: "",
+ name: "CallEcrecoverUnrecoverableKey",
+ },
+ {
+ input: "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" +
+ "000000000000000000000000000000000000000000000000000000000000001c" +
+ "73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f" +
+ "eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
+ expected: "000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ name: "ValidKey",
+ },
+ {
+ input: "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" +
+ "100000000000000000000000000000000000000000000000000000000000001c" +
+ "73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f" +
+ "eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
+ expected: "",
+ name: "InvalidHighV-bits-1",
+ },
+ {
+ input: "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" +
+ "000000000000000000000000000000000000001000000000000000000000001c" +
+ "73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f" +
+ "eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
+ expected: "",
+ name: "InvalidHighV-bits-2",
+ },
+ {
+ input: "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" +
+ "000000000000000000000000000000000000001000000000000000000000011c" +
+ "73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f" +
+ "eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
+ expected: "",
+ name: "InvalidHighV-bits-3",
+ },
+}
+
+func TestPrecompiledEcrecover(t *testing.T) {
+ for _, test := range ecRecoverTests {
+ testPrecompiled("01", test, t)
+ }
+
+}
diff --git a/core/vm/eips.go b/core/vm/eips.go
new file mode 100644
index 0000000000..40da1f88fa
--- /dev/null
+++ b/core/vm/eips.go
@@ -0,0 +1,93 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package vm
+
+import (
+ "fmt"
+
+ "github.com/XinFinOrg/XDPoSChain/params"
+)
+
+// EnableEIP enables the given EIP on the config.
+// This operation writes in-place, and callers need to ensure that the globally
+// defined jump tables are not polluted.
+func EnableEIP(eipNum int, jt *JumpTable) error {
+ switch eipNum {
+ case 2200:
+ enable2200(jt)
+ case 1884:
+ enable1884(jt)
+ case 1344:
+ enable1344(jt)
+ default:
+ return fmt.Errorf("undefined eip %d", eipNum)
+ }
+ return nil
+}
+
+// enable1884 applies EIP-1884 to the given jump table:
+// - Increase cost of BALANCE to 700
+// - Increase cost of EXTCODEHASH to 700
+// - Increase cost of SLOAD to 800
+// - Define SELFBALANCE, with cost GasFastStep (5)
+func enable1884(jt *JumpTable) {
+ // Gas cost changes
+ jt[SLOAD].constantGas = params.SloadGasEIP1884
+ jt[BALANCE].constantGas = params.BalanceGasEIP1884
+ jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884
+
+ // New opcode
+ jt[SELFBALANCE] = operation{
+ execute: opSelfBalance,
+ constantGas: GasFastStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ }
+}
+
+func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ balance := interpreter.intPool.get().Set(interpreter.evm.StateDB.GetBalance(callContext.contract.Address()))
+ callContext.stack.push(balance)
+ return nil, nil
+}
+
+// enable1344 applies EIP-1344 (ChainID Opcode)
+// - Adds an opcode that returns the current chain’s EIP-155 unique identifier
+func enable1344(jt *JumpTable) {
+ // New opcode
+ jt[CHAINID] = operation{
+ execute: opChainID,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ }
+}
+
+// opChainID implements CHAINID opcode
+func opChainID(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ chainId := interpreter.intPool.get().Set(interpreter.evm.chainConfig.ChainId)
+ callContext.stack.push(chainId)
+ return nil, nil
+}
+
+// enable2200 applies EIP-2200 (Rebalance net-metered SSTORE)
+func enable2200(jt *JumpTable) {
+ jt[SLOAD].constantGas = params.SloadGasEIP2200
+ jt[SSTORE].dynamicGas = gasSStoreEIP2200
+}
diff --git a/core/vm/errors.go b/core/vm/errors.go
index b19366be0e..c813aa36af 100644
--- a/core/vm/errors.go
+++ b/core/vm/errors.go
@@ -16,13 +16,51 @@
package vm
-import "errors"
+import (
+ "errors"
+ "fmt"
+)
+// List evm execution errors
var (
ErrOutOfGas = errors.New("out of gas")
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
ErrDepth = errors.New("max call depth exceeded")
- ErrTraceLimitReached = errors.New("the number of logs reached the specified limit")
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
ErrContractAddressCollision = errors.New("contract address collision")
+ ErrExecutionReverted = errors.New("execution reverted")
+ ErrMaxCodeSizeExceeded = errors.New("max code size exceeded")
+ ErrInvalidJump = errors.New("invalid jump destination")
+ ErrWriteProtection = errors.New("write protection")
+ ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
+ ErrGasUintOverflow = errors.New("gas uint64 overflow")
)
+
+// ErrStackUnderflow wraps an evm error when the items on the stack less
+// than the minimal requirement.
+type ErrStackUnderflow struct {
+ stackLen int
+ required int
+}
+
+func (e *ErrStackUnderflow) Error() string {
+ return fmt.Sprintf("stack underflow (%d <=> %d)", e.stackLen, e.required)
+}
+
+// ErrStackOverflow wraps an evm error when the items on the stack exceeds
+// the maximum allowance.
+type ErrStackOverflow struct {
+ stackLen int
+ limit int
+}
+
+func (e *ErrStackOverflow) Error() string {
+ return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.limit)
+}
+
+// ErrInvalidOpCode wraps an evm error when an invalid opcode is encountered.
+type ErrInvalidOpCode struct {
+ opcode OpCode
+}
+
+func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) }
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 96676c314a..f6f6a29a87 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -17,13 +17,16 @@
package vm
import (
+ "errors"
"math/big"
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
// emptyCodeHash is used by create to ensure deployment is disallowed to already
@@ -31,25 +34,54 @@ import (
var emptyCodeHash = crypto.Keccak256Hash(nil)
type (
+ // CanTransferFunc is the signature of a transfer guard function
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
- TransferFunc func(StateDB, common.Address, common.Address, *big.Int)
- // GetHashFunc returns the nth block hash in the blockchain
+ // TransferFunc is the signature of a transfer function
+ TransferFunc func(StateDB, common.Address, common.Address, *big.Int)
+ // GetHashFunc returns the n'th block hash in the blockchain
// and is used by the BLOCKHASH EVM op code.
GetHashFunc func(uint64) common.Hash
)
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
-func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) {
+func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
if contract.CodeAddr != nil {
precompiles := PrecompiledContractsHomestead
- if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
+ if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
+ if evm.chainRules.IsIstanbul {
+ precompiles = PrecompiledContractsIstanbul
+ }
if p := precompiles[*contract.CodeAddr]; p != nil {
+ switch p.(type) {
+ case *XDCxEpochPrice:
+ p.(*XDCxEpochPrice).SetTradingState(evm.tradingStateDB)
+ case *XDCxLastPrice:
+ p.(*XDCxLastPrice).SetTradingState(evm.tradingStateDB)
+ }
return RunPrecompiledContract(p, input, contract)
}
}
- return evm.interpreter.Run(contract, input)
+ if evm.ChainConfig().IsTIPXDCXCancellationFee(evm.BlockNumber) {
+ for _, interpreter := range evm.interpreters {
+ if interpreter.CanRun(contract.Code) {
+ if evm.interpreter != interpreter {
+ // Ensure that the interpreter pointer is set back
+ // to its current value upon return.
+ defer func(i Interpreter) {
+ evm.interpreter = i
+ }(evm.interpreter)
+ evm.interpreter = interpreter
+ }
+ return interpreter.Run(contract, input, readOnly)
+ }
+ }
+ } else {
+ return evm.interpreter.Run(contract, input, false)
+ }
+
+ return nil, errors.New("no compatible interpreter")
}
// Context provides the EVM with auxiliary information. Once provided
@@ -89,6 +121,9 @@ type EVM struct {
Context
// StateDB gives access to the underlying state
StateDB StateDB
+
+ tradingStateDB *tradingstate.TradingStateDB
+
// Depth is the current call stack
depth int
@@ -101,7 +136,8 @@ type EVM struct {
vmConfig Config
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
- interpreter *Interpreter
+ interpreters []Interpreter
+ interpreter Interpreter
// abort is used to abort the EVM calling operations
// NOTE: must be set atomically
abort int32
@@ -113,16 +149,22 @@ type EVM struct {
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
-func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
+func NewEVM(ctx Context, statedb StateDB, tradingStateDB *tradingstate.TradingStateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
evm := &EVM{
- Context: ctx,
- StateDB: statedb,
- vmConfig: vmConfig,
- chainConfig: chainConfig,
- chainRules: chainConfig.Rules(ctx.BlockNumber),
+ Context: ctx,
+ StateDB: statedb,
+ tradingStateDB: tradingStateDB,
+ vmConfig: vmConfig,
+ chainConfig: chainConfig,
+ chainRules: chainConfig.Rules(ctx.BlockNumber),
+ interpreters: make([]Interpreter, 0, 1),
}
- evm.interpreter = NewInterpreter(evm, vmConfig)
+ // vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
+ // as we always want to have the built-in EVM as the failover option.
+ evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
+ evm.interpreter = evm.interpreters[0]
+
return evm
}
@@ -132,6 +174,16 @@ func (evm *EVM) Cancel() {
atomic.StoreInt32(&evm.abort, 1)
}
+// Cancelled returns true if Cancel has been called
+func (evm *EVM) Cancelled() bool {
+ return atomic.LoadInt32(&evm.abort) == 1
+}
+
+// Interpreter returns the current interpreter
+func (evm *EVM) Interpreter() Interpreter {
+ return evm.interpreter
+}
+
// Call executes the contract associated with the addr with the given input as
// parameters. It also handles any necessary value transfer required and takes
// the necessary steps to create accounts and reverses the state in case of an
@@ -140,7 +192,6 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if evm.vmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
-
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
@@ -149,28 +200,37 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, ErrInsufficientBalance
}
-
var (
to = AccountRef(addr)
snapshot = evm.StateDB.Snapshot()
)
if !evm.StateDB.Exist(addr) {
precompiles := PrecompiledContractsHomestead
- if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
+ if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
- if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 {
+ if evm.ChainConfig().IsTIPXDCXCancellationFee(evm.BlockNumber) {
+ if evm.chainRules.IsIstanbul {
+ precompiles = PrecompiledContractsIstanbul
+ }
+ }
+ if precompiles[addr] == nil && evm.chainRules.IsEIP158 && value.Sign() == 0 {
+ // Calling a non existing account, don't do anything, but ping the tracer
+ if evm.vmConfig.Debug && evm.depth == 0 {
+ evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
+ evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
+ }
return nil, gas, nil
}
evm.StateDB.CreateAccount(addr)
}
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
-
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
+ // Even if the account has no code, we need to continue because it might be a precompile
start := time.Now()
// Capture the tracer start/end events in debug mode
@@ -181,14 +241,14 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
}()
}
- ret, err = run(evm, contract, input)
+ ret, err = run(evm, contract, input, false)
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in homestead this also counts for code storage gas errors.
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
- if err != errExecutionReverted {
+ if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
@@ -206,30 +266,30 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
if evm.vmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
-
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
// Fail if we're trying to transfer more than the available balance
- if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
+ // Note although it's noop to transfer X ether to caller itself. But
+ // if caller doesn't have enough balance, it would be an error to allow
+ // over-charging itself. So the check here is necessary.
+ if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, ErrInsufficientBalance
}
-
var (
snapshot = evm.StateDB.Snapshot()
to = AccountRef(caller.Address())
)
- // initialise a new contract and set the code that is to be used by the
- // EVM. The contract is a scoped environment for this execution context
- // only.
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
- ret, err = run(evm, contract, input)
+ ret, err = run(evm, contract, input, false)
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
- if err != errExecutionReverted {
+ if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
@@ -249,20 +309,18 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
-
var (
snapshot = evm.StateDB.Snapshot()
to = AccountRef(caller.Address())
)
-
// Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, to, nil, gas).AsDelegate()
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
- ret, err = run(evm, contract, input)
+ ret, err = run(evm, contract, input, false)
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
- if err != errExecutionReverted {
+ if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
@@ -281,40 +339,50 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
- // Make sure the readonly is only set if we aren't in readonly yet
- // this makes also sure that the readonly flag isn't removed for
- // child calls.
- if !evm.interpreter.readOnly {
- evm.interpreter.readOnly = true
- defer func() { evm.interpreter.readOnly = false }()
- }
-
var (
to = AccountRef(addr)
snapshot = evm.StateDB.Snapshot()
)
- // Initialise a new contract and set the code that is to be used by the
- // EVM. The contract is a scoped environment for this execution context
- // only.
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
contract := NewContract(caller, to, new(big.Int), gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
+ if evm.ChainConfig().IsTIPXDCXCancellationFee(evm.BlockNumber) {
+ // We do an AddBalance of zero here, just in order to trigger a touch.
+ // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
+ // but is the correct thing to do and matters on other networks, in tests, and potential
+ // future scenarios
+ evm.StateDB.AddBalance(addr, bigZero)
+ }
+
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
- ret, err = run(evm, contract, input)
+ ret, err = run(evm, contract, input, evm.ChainConfig().IsTIPXDCXCancellationFee(evm.BlockNumber))
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
- if err != errExecutionReverted {
+ if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
return ret, contract.Gas, err
}
-// Create creates a new contract using code as deployment code.
-func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+type codeAndHash struct {
+ code []byte
+ hash common.Hash
+}
+func (c *codeAndHash) Hash() common.Hash {
+ if c.hash == (common.Hash{}) {
+ c.hash = crypto.Keccak256Hash(c.code)
+ }
+ return c.hash
+}
+
+// create creates a new contract using code as deployment code.
+func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) {
// Depth check execution. Fail if we're trying to execute above the
// limit.
if evm.depth > int(params.CallCreateDepth) {
@@ -323,42 +391,40 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, common.Address{}, gas, ErrInsufficientBalance
}
- // Ensure there's no existing contract already at the designated address
nonce := evm.StateDB.GetNonce(caller.Address())
evm.StateDB.SetNonce(caller.Address(), nonce+1)
- contractAddr = crypto.CreateAddress(caller.Address(), nonce)
- contractHash := evm.StateDB.GetCodeHash(contractAddr)
- if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
+ // Ensure there's no existing contract already at the designated address
+ contractHash := evm.StateDB.GetCodeHash(address)
+ if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
return nil, common.Address{}, 0, ErrContractAddressCollision
}
// Create a new account on the state
snapshot := evm.StateDB.Snapshot()
- evm.StateDB.CreateAccount(contractAddr)
- if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
- evm.StateDB.SetNonce(contractAddr, 1)
+ evm.StateDB.CreateAccount(address)
+ if evm.chainRules.IsEIP158 {
+ evm.StateDB.SetNonce(address, 1)
}
- evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
+ evm.Transfer(evm.StateDB, caller.Address(), address, value)
- // initialise a new contract and set the code that is to be used by the
- // EVM. The contract is a scoped environment for this execution context
- // only.
- contract := NewContract(caller, AccountRef(contractAddr), value, gas)
- contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(caller, AccountRef(address), value, gas)
+ contract.SetCodeOptionalHash(&address, codeAndHash)
if evm.vmConfig.NoRecursion && evm.depth > 0 {
- return nil, contractAddr, gas, nil
+ return nil, address, gas, nil
}
if evm.vmConfig.Debug && evm.depth == 0 {
- evm.vmConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, value)
+ evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
}
start := time.Now()
- ret, err = run(evm, contract, nil)
+ ret, err := run(evm, contract, nil, false)
// check whether the max code size has been exceeded
- maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize
+ maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize
// if the contract creation ran successfully and no errors were returned
// calculate the gas required to store the code. If the code could not
// be stored due to not enough gas set an error and let it be handled
@@ -366,7 +432,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
if err == nil && !maxCodeSizeExceeded {
createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) {
- evm.StateDB.SetCode(contractAddr, ret)
+ evm.StateDB.SetCode(address, ret)
} else {
err = ErrCodeStoreOutOfGas
}
@@ -375,24 +441,38 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in homestead this also counts for code storage gas errors.
- if maxCodeSizeExceeded || (err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
+ if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) {
evm.StateDB.RevertToSnapshot(snapshot)
- if err != errExecutionReverted {
+ if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
// Assign err if contract code size exceeds the max while the err is still empty.
if maxCodeSizeExceeded && err == nil {
- err = errMaxCodeSizeExceeded
+ err = ErrMaxCodeSizeExceeded
}
if evm.vmConfig.Debug && evm.depth == 0 {
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
}
- return ret, contractAddr, contract.Gas, err
+ return ret, address, contract.Gas, err
+
+}
+
+// Create creates a new contract using code as deployment code.
+func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+ contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
+ return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr)
+}
+
+// Create2 creates a new contract using code as deployment code.
+//
+// The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:]
+// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
+func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+ codeAndHash := &codeAndHash{code: code}
+ contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes())
+ return evm.create(caller, codeAndHash, gas, endowment, contractAddr)
}
// ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
-
-// Interpreter returns the EVM interpreter
-func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter }
diff --git a/core/vm/gas.go b/core/vm/gas.go
index dd64d5f178..bda326cdc7 100644
--- a/core/vm/gas.go
+++ b/core/vm/gas.go
@@ -18,10 +18,9 @@ package vm
import (
"math/big"
-
- "github.com/ethereum/go-ethereum/params"
)
+// Gas costs
const (
GasQuickStep uint64 = 2
GasFastestStep uint64 = 3
@@ -29,29 +28,25 @@ const (
GasMidStep uint64 = 8
GasSlowStep uint64 = 10
GasExtStep uint64 = 20
-
- GasReturn uint64 = 0
- GasStop uint64 = 0
- GasContractByte uint64 = 200
)
-// calcGas returns the actual gas cost of the call.
+// callGas returns the actual gas cost of the call.
//
-// The cost of gas was changed during the homestead price change HF. To allow for EIP150
-// to be implemented. The returned gas is gas - base * 63 / 64.
-func callGas(gasTable params.GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) {
- if gasTable.CreateBySuicide > 0 {
+// The cost of gas was changed during the homestead price change HF.
+// As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64.
+func callGas(isEip150 bool, availableGas, base uint64, callCost *big.Int) (uint64, error) {
+ if isEip150 {
availableGas = availableGas - base
gas := availableGas - availableGas/64
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
- // is smaller than the requested amount. Therefor we return the new gas instead
+ // is smaller than the requested amount. Therefore we return the new gas instead
// of returning an error.
- if callCost.BitLen() > 64 || gas < callCost.Uint64() {
+ if !callCost.IsUint64() || gas < callCost.Uint64() {
return gas, nil
}
}
- if callCost.BitLen() > 64 {
- return 0, errGasUintOverflow
+ if !callCost.IsUint64() {
+ return 0, ErrGasUintOverflow
}
return callCost.Uint64(), nil
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index 83adba428e..987dca3238 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -17,29 +17,28 @@
package vm
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
+ "errors"
+
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
-// memoryGasCosts calculates the quadratic gas for memory expansion. It does so
+// memoryGasCost calculates the quadratic gas for memory expansion. It does so
// only for the memory region that is expanded, not the total memory.
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
-
if newMemSize == 0 {
return 0, nil
}
- // The maximum that will fit in a uint64 is max_word_count - 1
- // anything above that will result in an overflow.
- // Additionally, a newMemSize which results in a
- // newMemSizeWords larger than 0x7ffffffff will cause the square operation
- // to overflow.
- // The constant 0xffffffffe0 is the highest number that can be used without
- // overflowing the gas calculation
- if newMemSize > 0xffffffffe0 {
- return 0, errGasUintOverflow
+ // The maximum that will fit in a uint64 is max_word_count - 1. Anything above
+ // that will result in an overflow. Additionally, a newMemSize which results in
+ // a newMemSizeWords larger than 0xFFFFFFFF will cause the square operation to
+ // overflow. The constant 0x1FFFFFFFE0 is the highest number that can be used
+ // without overflowing the gas calculation.
+ if newMemSize > 0x1FFFFFFFE0 {
+ return 0, ErrGasUintOverflow
}
-
newMemSizeWords := toWordSize(newMemSize)
newMemSize = newMemSizeWords * 32
@@ -57,91 +56,173 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
return 0, nil
}
-func constGasFunc(gas uint64) gasFunc {
- return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+// memoryCopierGas creates the gas functions for the following opcodes, and takes
+// the stack position of the operand which determines the size of the data to copy
+// as argument:
+// CALLDATACOPY (stack position 2)
+// CODECOPY (stack position 2)
+// EXTCODECOPY (stack poition 3)
+// RETURNDATACOPY (stack position 2)
+func memoryCopierGas(stackpos int) gasFunc {
+ return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ // Gas for expanding the memory
+ gas, err := memoryGasCost(mem, memorySize)
+ if err != nil {
+ return 0, err
+ }
+ // And gas for copying data, charged per word at param.CopyGas
+ words, overflow := bigUint64(stack.Back(stackpos))
+ if overflow {
+ return 0, ErrGasUintOverflow
+ }
+
+ if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
+ return 0, ErrGasUintOverflow
+ }
+
+ if gas, overflow = math.SafeAdd(gas, words); overflow {
+ return 0, ErrGasUintOverflow
+ }
return gas, nil
}
}
-func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
+var (
+ gasCallDataCopy = memoryCopierGas(2)
+ gasCodeCopy = memoryCopierGas(2)
+ gasExtCodeCopy = memoryCopierGas(3)
+ gasReturnDataCopy = memoryCopierGas(2)
+)
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
- words, overflow := bigUint64(stack.Back(2))
- if overflow {
- return 0, errGasUintOverflow
- }
-
- if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
-
- if gas, overflow = math.SafeAdd(gas, words); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
- words, overflow := bigUint64(stack.Back(2))
- if overflow {
- return 0, errGasUintOverflow
- }
-
- if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
-
- if gas, overflow = math.SafeAdd(gas, words); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var (
- y, x = stack.Back(1), stack.Back(0)
- val = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
+ y, x = stack.Back(1), stack.Back(0)
+ current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
)
- // This checks for 3 scenario's and calculates gas accordingly
- // 1. From a zero-value address to a non-zero value (NEW VALUE)
- // 2. From a non-zero value address to a zero-value address (DELETE)
- // 3. From a non-zero to a non-zero (CHANGE)
- if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) {
- // 0 => non 0
- return params.SstoreSetGas, nil
- } else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) {
- evm.StateDB.AddRefund(params.SstoreRefundGas)
-
- return params.SstoreClearGas, nil
- } else {
- // non 0 => non 0 (or 0 => 0)
- return params.SstoreResetGas, nil
+ // The legacy gas metering only takes into consideration the current state
+ // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283)
+ // OR Constantinople is not active
+ if evm.chainRules.IsPetersburg || !evm.chainRules.IsConstantinople {
+ // This checks for 3 scenario's and calculates gas accordingly:
+ //
+ // 1. From a zero-value address to a non-zero value (NEW VALUE)
+ // 2. From a non-zero value address to a zero-value address (DELETE)
+ // 3. From a non-zero to a non-zero (CHANGE)
+ switch {
+ case current == (common.Hash{}) && y.Sign() != 0: // 0 => non 0
+ return params.SstoreSetGas, nil
+ case current != (common.Hash{}) && y.Sign() == 0: // non 0 => 0
+ evm.StateDB.AddRefund(params.SstoreRefundGas)
+ return params.SstoreClearGas, nil
+ default: // non 0 => non 0 (or 0 => 0)
+ return params.SstoreResetGas, nil
+ }
}
+ // The new gas metering is based on net gas costs (EIP-1283):
+ //
+ // 1. If current value equals new value (this is a no-op), 200 gas is deducted.
+ // 2. If current value does not equal new value
+ // 2.1. If original value equals current value (this storage slot has not been changed by the current execution context)
+ // 2.1.1. If original value is 0, 20000 gas is deducted.
+ // 2.1.2. Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter.
+ // 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses.
+ // 2.2.1. If original value is not 0
+ // 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0.
+ // 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
+ // 2.2.2. If original value equals new value (this storage slot is reset)
+ // 2.2.2.1. If original value is 0, add 19800 gas to refund counter.
+ // 2.2.2.2. Otherwise, add 4800 gas to refund counter.
+ value := common.BigToHash(y)
+ if current == value { // noop (1)
+ return params.NetSstoreNoopGas, nil
+ }
+ original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x))
+ if original == current {
+ if original == (common.Hash{}) { // create slot (2.1.1)
+ return params.NetSstoreInitGas, nil
+ }
+ if value == (common.Hash{}) { // delete slot (2.1.2b)
+ evm.StateDB.AddRefund(params.NetSstoreClearRefund)
+ }
+ return params.NetSstoreCleanGas, nil // write existing slot (2.1.2)
+ }
+ if original != (common.Hash{}) {
+ if current == (common.Hash{}) { // recreate slot (2.2.1.1)
+ evm.StateDB.SubRefund(params.NetSstoreClearRefund)
+ } else if value == (common.Hash{}) { // delete slot (2.2.1.2)
+ evm.StateDB.AddRefund(params.NetSstoreClearRefund)
+ }
+ }
+ if original == value {
+ if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
+ evm.StateDB.AddRefund(params.NetSstoreResetClearRefund)
+ } else { // reset to original existing slot (2.2.2.2)
+ evm.StateDB.AddRefund(params.NetSstoreResetRefund)
+ }
+ }
+ return params.NetSstoreDirtyGas, nil
+}
+
+// 0. If *gasleft* is less than or equal to 2300, fail the current call.
+// 1. If current value equals new value (this is a no-op), SSTORE_NOOP_GAS gas is deducted.
+// 2. If current value does not equal new value:
+// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context):
+// 2.1.1. If original value is 0, SSTORE_INIT_GAS gas is deducted.
+// 2.1.2. Otherwise, SSTORE_CLEAN_GAS gas is deducted. If new value is 0, add SSTORE_CLEAR_REFUND to refund counter.
+// 2.2. If original value does not equal current value (this storage slot is dirty), SSTORE_DIRTY_GAS gas is deducted. Apply both of the following clauses:
+// 2.2.1. If original value is not 0:
+// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEAR_REFUND gas from refund counter. We can prove that refund counter will never go below 0.
+// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEAR_REFUND gas to refund counter.
+// 2.2.2. If original value equals new value (this storage slot is reset):
+// 2.2.2.1. If original value is 0, add SSTORE_INIT_REFUND to refund counter.
+// 2.2.2.2. Otherwise, add SSTORE_CLEAN_REFUND gas to refund counter.
+func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ // If we fail the minimum gas availability invariant, fail (0)
+ if contract.Gas <= params.SstoreSentryGasEIP2200 {
+ return 0, errors.New("not enough gas for reentrancy sentry")
+ }
+ // Gas sentry honoured, do the actual gas calculation based on the stored value
+ var (
+ y, x = stack.Back(1), stack.Back(0)
+ current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
+ )
+ value := common.BigToHash(y)
+
+ if current == value { // noop (1)
+ return params.SstoreNoopGasEIP2200, nil
+ }
+ original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x))
+ if original == current {
+ if original == (common.Hash{}) { // create slot (2.1.1)
+ return params.SstoreInitGasEIP2200, nil
+ }
+ if value == (common.Hash{}) { // delete slot (2.1.2b)
+ evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200)
+ }
+ return params.SstoreCleanGasEIP2200, nil // write existing slot (2.1.2)
+ }
+ if original != (common.Hash{}) {
+ if current == (common.Hash{}) { // recreate slot (2.2.1.1)
+ evm.StateDB.SubRefund(params.SstoreClearRefundEIP2200)
+ } else if value == (common.Hash{}) { // delete slot (2.2.1.2)
+ evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200)
+ }
+ }
+ if original == value {
+ if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
+ evm.StateDB.AddRefund(params.SstoreInitRefundEIP2200)
+ } else { // reset to original existing slot (2.2.2.2)
+ evm.StateDB.AddRefund(params.SstoreCleanRefundEIP2200)
+ }
+ }
+ return params.SstoreDirtyGasEIP2200, nil // dirty update (2.2)
}
func makeGasLog(n uint64) gasFunc {
- return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
requestedSize, overflow := bigUint64(stack.Back(1))
if overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
gas, err := memoryGasCost(mem, memorySize)
@@ -150,178 +231,108 @@ func makeGasLog(n uint64) gasFunc {
}
if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
var memorySizeGas uint64
if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
}
-func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
+func gasSha3(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
-
- if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow {
- return 0, errGasUintOverflow
- }
-
wordGas, overflow := bigUint64(stack.Back(1))
if overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
-func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+// pureMemoryGascost is used by several operations, which aside from their
+// static cost have a dynamic cost which is solely based on the memory
+// expansion
+func pureMemoryGascost(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ return memoryGasCost(mem, memorySize)
+}
+
+var (
+ gasReturn = pureMemoryGascost
+ gasRevert = pureMemoryGascost
+ gasMLoad = pureMemoryGascost
+ gasMStore8 = pureMemoryGascost
+ gasMStore = pureMemoryGascost
+ gasCreate = pureMemoryGascost
+)
+
+func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
wordGas, overflow := bigUint64(stack.Back(2))
if overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
- if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
- return 0, errGasUintOverflow
+ if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow {
+ return 0, ErrGasUintOverflow
}
if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
-func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow {
- return 0, errGasUintOverflow
- }
-
- wordGas, overflow := bigUint64(stack.Back(3))
- if overflow {
- return 0, errGasUintOverflow
- }
-
- if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
-
- if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, errGasUintOverflow
- }
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, errGasUintOverflow
- }
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, errGasUintOverflow
- }
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
- if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.Balance, nil
-}
-
-func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.ExtcodeSize, nil
-}
-
-func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.SLoad, nil
-}
-
-func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasExpFrontier(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
var (
- gas = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas
+ gas = expByteLen * params.ExpByteFrontier // no overflow check required. Max is 256 * ExpByte gas
overflow bool
)
- if gas, overflow = math.SafeAdd(gas, GasSlowStep); overflow {
- return 0, errGasUintOverflow
+ if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
-func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
+
var (
- gas = gt.Calls
+ gas = expByteLen * params.ExpByteEIP158 // no overflow check required. Max is 256 * ExpByte gas
+ overflow bool
+ )
+ if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
+ return 0, ErrGasUintOverflow
+ }
+ return gas, nil
+}
+
+func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ var (
+ gas uint64
transfersValue = stack.Back(2).Sign() != 0
address = common.BigToAddress(stack.Back(1))
- eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
)
- if eip158 {
+ if evm.chainRules.IsEIP158 {
if transfersValue && evm.StateDB.Empty(address) {
gas += params.CallNewAccountGas
}
@@ -337,125 +348,95 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
}
var overflow bool
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
-func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas := gt.Calls
- if stack.Back(2).Sign() != 0 {
- gas += params.CallValueTransferGas
- }
+func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
memoryGas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
- return 0, errGasUintOverflow
+ var (
+ gas uint64
+ overflow bool
+ )
+ if stack.Back(2).Sign() != 0 {
+ gas += params.CallValueTransferGas
}
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
+ return 0, ErrGasUintOverflow
+ }
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
- return 0, errGasUintOverflow
+ return 0, ErrGasUintOverflow
}
return gas, nil
}
-func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return memoryGasCost(mem, memorySize)
+func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ gas, err := memoryGasCost(mem, memorySize)
+ if err != nil {
+ return 0, err
+ }
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+ if err != nil {
+ return 0, err
+ }
+ var overflow bool
+ if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ return 0, ErrGasUintOverflow
+ }
+ return gas, nil
}
-func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return memoryGasCost(mem, memorySize)
+func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ gas, err := memoryGasCost(mem, memorySize)
+ if err != nil {
+ return 0, err
+ }
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+ if err != nil {
+ return 0, err
+ }
+ var overflow bool
+ if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ return 0, ErrGasUintOverflow
+ }
+ return gas, nil
}
-func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var gas uint64
// EIP150 homestead gas reprice fork:
- if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
- gas = gt.Suicide
- var (
- address = common.BigToAddress(stack.Back(0))
- eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
- )
+ if evm.chainRules.IsEIP150 {
+ gas = params.SelfdestructGasEIP150
+ var address = common.BigToAddress(stack.Back(0))
- if eip158 {
+ if evm.chainRules.IsEIP158 {
// if empty and transfers value
if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
- gas += gt.CreateBySuicide
+ gas += params.CreateBySelfdestructGas
}
} else if !evm.StateDB.Exist(address) {
- gas += gt.CreateBySuicide
+ gas += params.CreateBySelfdestructGas
}
}
if !evm.StateDB.HasSuicided(contract.Address()) {
- evm.StateDB.AddRefund(params.SuicideRefundGas)
+ evm.StateDB.AddRefund(params.SelfdestructRefundGas)
}
return gas, nil
}
-
-func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
- return 0, errGasUintOverflow
- }
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
- if err != nil {
- return 0, err
- }
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
- return 0, errGasUintOverflow
- }
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
- if err != nil {
- return 0, err
- }
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasPush(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return GasFastestStep, nil
-}
-
-func gasSwap(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return GasFastestStep, nil
-}
-
-func gasDup(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return GasFastestStep, nil
-}
diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go
index 1b91aee56c..501a0364c6 100644
--- a/core/vm/gas_table_test.go
+++ b/core/vm/gas_table_test.go
@@ -16,21 +16,93 @@
package vm
-import "testing"
+import (
+ "math"
+ "math/big"
+ "testing"
+
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/params"
+)
func TestMemoryGasCost(t *testing.T) {
- //size := uint64(math.MaxUint64 - 64)
- size := uint64(0xffffffffe0)
- v, err := memoryGasCost(&Memory{}, size)
- if err != nil {
- t.Error("didn't expect error:", err)
+ tests := []struct {
+ size uint64
+ cost uint64
+ overflow bool
+ }{
+ {0x1fffffffe0, 36028809887088637, false},
+ {0x1fffffffe1, 0, true},
}
- if v != 36028899963961341 {
- t.Errorf("Expected: 36028899963961341, got %d", v)
- }
-
- _, err = memoryGasCost(&Memory{}, size+1)
- if err == nil {
- t.Error("expected error")
+ for i, tt := range tests {
+ v, err := memoryGasCost(&Memory{}, tt.size)
+ if (err == ErrGasUintOverflow) != tt.overflow {
+ t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == ErrGasUintOverflow, tt.overflow)
+ }
+ if v != tt.cost {
+ t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost)
+ }
+ }
+}
+
+var eip2200Tests = []struct {
+ original byte
+ gaspool uint64
+ input string
+ used uint64
+ refund uint64
+ failure error
+}{
+ {0, math.MaxUint64, "0x60006000556000600055", 1612, 0, nil}, // 0 -> 0 -> 0
+ {0, math.MaxUint64, "0x60006000556001600055", 20812, 0, nil}, // 0 -> 0 -> 1
+ {0, math.MaxUint64, "0x60016000556000600055", 20812, 19200, nil}, // 0 -> 1 -> 0
+ {0, math.MaxUint64, "0x60016000556002600055", 20812, 0, nil}, // 0 -> 1 -> 2
+ {0, math.MaxUint64, "0x60016000556001600055", 20812, 0, nil}, // 0 -> 1 -> 1
+ {1, math.MaxUint64, "0x60006000556000600055", 5812, 15000, nil}, // 1 -> 0 -> 0
+ {1, math.MaxUint64, "0x60006000556001600055", 5812, 4200, nil}, // 1 -> 0 -> 1
+ {1, math.MaxUint64, "0x60006000556002600055", 5812, 0, nil}, // 1 -> 0 -> 2
+ {1, math.MaxUint64, "0x60026000556000600055", 5812, 15000, nil}, // 1 -> 2 -> 0
+ {1, math.MaxUint64, "0x60026000556003600055", 5812, 0, nil}, // 1 -> 2 -> 3
+ {1, math.MaxUint64, "0x60026000556001600055", 5812, 4200, nil}, // 1 -> 2 -> 1
+ {1, math.MaxUint64, "0x60026000556002600055", 5812, 0, nil}, // 1 -> 2 -> 2
+ {1, math.MaxUint64, "0x60016000556000600055", 5812, 15000, nil}, // 1 -> 1 -> 0
+ {1, math.MaxUint64, "0x60016000556002600055", 5812, 0, nil}, // 1 -> 1 -> 2
+ {1, math.MaxUint64, "0x60016000556001600055", 1612, 0, nil}, // 1 -> 1 -> 1
+ {0, math.MaxUint64, "0x600160005560006000556001600055", 40818, 19200, nil}, // 0 -> 1 -> 0 -> 1
+ {1, math.MaxUint64, "0x600060005560016000556000600055", 10818, 19200, nil}, // 1 -> 0 -> 1 -> 0
+ {1, 2306, "0x6001600055", 2306, 0, ErrOutOfGas}, // 1 -> 1 (2300 sentry + 2xPUSH)
+ {1, 2307, "0x6001600055", 806, 0, nil}, // 1 -> 1 (2301 sentry + 2xPUSH)
+}
+
+func TestEIP2200(t *testing.T) {
+ for i, tt := range eip2200Tests {
+ address := common.BytesToAddress([]byte("contract"))
+ db := rawdb.NewMemoryDatabase()
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
+ statedb.CreateAccount(address)
+ statedb.SetCode(address, hexutil.MustDecode(tt.input))
+ statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
+ statedb.Finalise(true) // Push the state into the "original" slot
+
+ vmctx := Context{
+ CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true },
+ Transfer: func(StateDB, common.Address, common.Address, *big.Int) {},
+ }
+ vmenv := NewEVM(vmctx, statedb, nil, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
+
+ _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int))
+ if err != tt.failure {
+ t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
+ }
+ if used := tt.gaspool - gas; used != tt.used {
+ t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used)
+ }
+ if refund := vmenv.StateDB.GetRefund(); refund != tt.refund {
+ t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund)
+ }
}
}
diff --git a/core/vm/gen_structlog.go b/core/vm/gen_structlog.go
index ade3ca6318..8a689c1ce1 100644
--- a/core/vm/gen_structlog.go
+++ b/core/vm/gen_structlog.go
@@ -6,27 +6,29 @@ import (
"encoding/json"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
var _ = (*structLogMarshaling)(nil)
+// MarshalJSON marshals as JSON.
func (s StructLog) MarshalJSON() ([]byte, error) {
type StructLog struct {
- Pc uint64 `json:"pc"`
- Op OpCode `json:"op"`
- Gas math.HexOrDecimal64 `json:"gas"`
- GasCost math.HexOrDecimal64 `json:"gasCost"`
- Memory hexutil.Bytes `json:"memory"`
- MemorySize int `json:"memSize"`
- Stack []*math.HexOrDecimal256 `json:"stack"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth int `json:"depth"`
- Err error `json:"-"`
- OpName string `json:"opName"`
- ErrorString string `json:"error"`
+ Pc uint64 `json:"pc"`
+ Op OpCode `json:"op"`
+ Gas math.HexOrDecimal64 `json:"gas"`
+ GasCost math.HexOrDecimal64 `json:"gasCost"`
+ Memory hexutil.Bytes `json:"memory"`
+ MemorySize int `json:"memSize"`
+ Stack []*math.HexOrDecimal256 `json:"stack"`
+ Storage map[common.Hash]common.Hash `json:"-"`
+ Depth int `json:"depth"`
+ RefundCounter uint64 `json:"refund"`
+ Err error `json:"-"`
+ OpName string `json:"opName"`
+ ErrorString string `json:"error"`
}
var enc StructLog
enc.Pc = s.Pc
@@ -43,24 +45,27 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
}
enc.Storage = s.Storage
enc.Depth = s.Depth
+ enc.RefundCounter = s.RefundCounter
enc.Err = s.Err
enc.OpName = s.OpName()
enc.ErrorString = s.ErrorString()
return json.Marshal(&enc)
}
+// UnmarshalJSON unmarshals from JSON.
func (s *StructLog) UnmarshalJSON(input []byte) error {
type StructLog struct {
- Pc *uint64 `json:"pc"`
- Op *OpCode `json:"op"`
- Gas *math.HexOrDecimal64 `json:"gas"`
- GasCost *math.HexOrDecimal64 `json:"gasCost"`
- Memory *hexutil.Bytes `json:"memory"`
- MemorySize *int `json:"memSize"`
- Stack []*math.HexOrDecimal256 `json:"stack"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth *int `json:"depth"`
- Err error `json:"-"`
+ Pc *uint64 `json:"pc"`
+ Op *OpCode `json:"op"`
+ Gas *math.HexOrDecimal64 `json:"gas"`
+ GasCost *math.HexOrDecimal64 `json:"gasCost"`
+ Memory *hexutil.Bytes `json:"memory"`
+ MemorySize *int `json:"memSize"`
+ Stack []*math.HexOrDecimal256 `json:"stack"`
+ Storage map[common.Hash]common.Hash `json:"-"`
+ Depth *int `json:"depth"`
+ RefundCounter *uint64 `json:"refund"`
+ Err error `json:"-"`
}
var dec StructLog
if err := json.Unmarshal(input, &dec); err != nil {
@@ -96,6 +101,9 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
if dec.Depth != nil {
s.Depth = *dec.Depth
}
+ if dec.RefundCounter != nil {
+ s.RefundCounter = *dec.RefundCounter
+ }
if dec.Err != nil {
s.Err = dec.Err
}
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 1e494a0eb8..4f1d122911 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -17,69 +17,63 @@
package vm
import (
- "errors"
- "fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "golang.org/x/crypto/sha3"
)
var (
- bigZero = new(big.Int)
- tt255 = math.BigPow(2, 255)
- tt256 = math.BigPow(2, 256)
- errWriteProtection = errors.New("evm: write protection")
- errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
- errExecutionReverted = errors.New("evm: execution reverted")
- errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
+ bigZero = new(big.Int)
+ tt255 = math.BigPow(2, 255)
)
-func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opAdd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
math.U256(y.Add(x, y))
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
math.U256(y.Sub(x, y))
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.pop()
- stack.push(math.U256(x.Mul(x, y)))
+func opMul(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.pop()
+ callContext.stack.push(math.U256(x.Mul(x, y)))
- evm.interpreter.intPool.put(y)
+ interpreter.intPool.putOne(y)
return nil, nil
}
-func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opDiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
if y.Sign() != 0 {
math.U256(y.Div(x, y))
} else {
y.SetUint64(0)
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := math.S256(stack.pop()), math.S256(stack.pop())
- res := evm.interpreter.intPool.getZero()
+func opSdiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := math.S256(callContext.stack.pop()), math.S256(callContext.stack.pop())
+ res := interpreter.intPool.getZero()
if y.Sign() == 0 || x.Sign() == 0 {
- stack.push(res)
+ callContext.stack.push(res)
} else {
if x.Sign() != y.Sign() {
res.Div(x.Abs(x), y.Abs(y))
@@ -87,29 +81,29 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
} else {
res.Div(x.Abs(x), y.Abs(y))
}
- stack.push(math.U256(res))
+ callContext.stack.push(math.U256(res))
}
- evm.interpreter.intPool.put(x, y)
+ interpreter.intPool.put(x, y)
return nil, nil
}
-func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.pop()
+func opMod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.pop()
if y.Sign() == 0 {
- stack.push(x.SetUint64(0))
+ callContext.stack.push(x.SetUint64(0))
} else {
- stack.push(math.U256(x.Mod(x, y)))
+ callContext.stack.push(math.U256(x.Mod(x, y)))
}
- evm.interpreter.intPool.put(y)
+ interpreter.intPool.putOne(y)
return nil, nil
}
-func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := math.S256(stack.pop()), math.S256(stack.pop())
- res := evm.interpreter.intPool.getZero()
+func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := math.S256(callContext.stack.pop()), math.S256(callContext.stack.pop())
+ res := interpreter.intPool.getZero()
if y.Sign() == 0 {
- stack.push(res)
+ callContext.stack.push(res)
} else {
if x.Sign() < 0 {
res.Mod(x.Abs(x), y.Abs(y))
@@ -117,26 +111,38 @@ func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
} else {
res.Mod(x.Abs(x), y.Abs(y))
}
- stack.push(math.U256(res))
+ callContext.stack.push(math.U256(res))
}
- evm.interpreter.intPool.put(x, y)
+ interpreter.intPool.put(x, y)
return nil, nil
}
-func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- base, exponent := stack.pop(), stack.pop()
- stack.push(math.Exp(base, exponent))
-
- evm.interpreter.intPool.put(base, exponent)
-
+func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ base, exponent := callContext.stack.pop(), callContext.stack.pop()
+ // some shortcuts
+ cmpToOne := exponent.Cmp(big1)
+ if cmpToOne < 0 { // Exponent is zero
+ // x ^ 0 == 1
+ callContext.stack.push(base.SetUint64(1))
+ } else if base.Sign() == 0 {
+ // 0 ^ y, if y != 0, == 0
+ callContext.stack.push(base.SetUint64(0))
+ } else if cmpToOne == 0 { // Exponent is one
+ // x ^ 1 == x
+ callContext.stack.push(base)
+ } else {
+ callContext.stack.push(math.Exp(base, exponent))
+ interpreter.intPool.putOne(base)
+ }
+ interpreter.intPool.putOne(exponent)
return nil, nil
}
-func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- back := stack.pop()
+func opSignExtend(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ back := callContext.stack.pop()
if back.Cmp(big.NewInt(31)) < 0 {
bit := uint(back.Uint64()*8 + 7)
- num := stack.pop()
+ num := callContext.stack.pop()
mask := back.Lsh(common.Big1, bit)
mask.Sub(mask, common.Big1)
if num.Bit(int(bit)) > 0 {
@@ -145,43 +151,43 @@ func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac
num.And(num, mask)
}
- stack.push(math.U256(num))
+ callContext.stack.push(math.U256(num))
}
- evm.interpreter.intPool.put(back)
+ interpreter.intPool.putOne(back)
return nil, nil
}
-func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x := stack.peek()
+func opNot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x := callContext.stack.peek()
math.U256(x.Not(x))
return nil, nil
}
-func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
if x.Cmp(y) < 0 {
y.SetUint64(1)
} else {
y.SetUint64(0)
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opGt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
if x.Cmp(y) > 0 {
y.SetUint64(1)
} else {
y.SetUint64(0)
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opSlt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
xSign := x.Cmp(tt255)
ySign := y.Cmp(tt255)
@@ -200,12 +206,12 @@ func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
y.SetUint64(0)
}
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opSgt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
xSign := x.Cmp(tt255)
ySign := y.Cmp(tt255)
@@ -224,23 +230,23 @@ func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
y.SetUint64(0)
}
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opEq(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
if x.Cmp(y) == 0 {
y.SetUint64(1)
} else {
y.SetUint64(0)
}
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x := stack.peek()
+func opIszero(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x := callContext.stack.peek()
if x.Sign() > 0 {
x.SetUint64(0)
} else {
@@ -249,75 +255,75 @@ func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S
return nil, nil
}
-func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.pop()
- stack.push(x.And(x, y))
+func opAnd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.pop()
+ callContext.stack.push(x.And(x, y))
- evm.interpreter.intPool.put(y)
+ interpreter.intPool.putOne(y)
return nil, nil
}
-func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opOr(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
y.Or(x, y)
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y := stack.pop(), stack.peek()
+func opXor(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y := callContext.stack.pop(), callContext.stack.peek()
y.Xor(x, y)
- evm.interpreter.intPool.put(x)
+ interpreter.intPool.putOne(x)
return nil, nil
}
-func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- th, val := stack.pop(), stack.peek()
+func opByte(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ th, val := callContext.stack.pop(), callContext.stack.peek()
if th.Cmp(common.Big32) < 0 {
b := math.Byte(val, 32, int(th.Int64()))
val.SetUint64(uint64(b))
} else {
val.SetUint64(0)
}
- evm.interpreter.intPool.put(th)
+ interpreter.intPool.putOne(th)
return nil, nil
}
-func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y, z := stack.pop(), stack.pop(), stack.pop()
+func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
if z.Cmp(bigZero) > 0 {
x.Add(x, y)
x.Mod(x, z)
- stack.push(math.U256(x))
+ callContext.stack.push(math.U256(x))
} else {
- stack.push(x.SetUint64(0))
+ callContext.stack.push(x.SetUint64(0))
}
- evm.interpreter.intPool.put(y, z)
+ interpreter.intPool.put(y, z)
return nil, nil
}
-func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- x, y, z := stack.pop(), stack.pop(), stack.pop()
+func opMulmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
if z.Cmp(bigZero) > 0 {
x.Mul(x, y)
x.Mod(x, z)
- stack.push(math.U256(x))
+ callContext.stack.push(math.U256(x))
} else {
- stack.push(x.SetUint64(0))
+ callContext.stack.push(x.SetUint64(0))
}
- evm.interpreter.intPool.put(y, z)
+ interpreter.intPool.put(y, z)
return nil, nil
}
// opSHL implements Shift Left
// The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the left by arg1 number of bits.
-func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opSHL(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
- shift, value := math.U256(stack.pop()), math.U256(stack.peek())
- defer evm.interpreter.intPool.put(shift) // First operand back into the pool
+ shift, value := math.U256(callContext.stack.pop()), math.U256(callContext.stack.peek())
+ defer interpreter.intPool.putOne(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
value.SetUint64(0)
@@ -332,10 +338,10 @@ func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
// opSHR implements Logical Shift Right
// The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
-func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opSHR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
- shift, value := math.U256(stack.pop()), math.U256(stack.peek())
- defer evm.interpreter.intPool.put(shift) // First operand back into the pool
+ shift, value := math.U256(callContext.stack.pop()), math.U256(callContext.stack.peek())
+ defer interpreter.intPool.putOne(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
value.SetUint64(0)
@@ -350,455 +356,528 @@ func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
// opSAR implements Arithmetic Shift Right
// The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
-func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opSAR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
- shift, value := math.U256(stack.pop()), math.S256(stack.pop())
- defer evm.interpreter.intPool.put(shift) // First operand back into the pool
+ shift, value := math.U256(callContext.stack.pop()), math.S256(callContext.stack.pop())
+ defer interpreter.intPool.putOne(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
- if value.Sign() > 0 {
+ if value.Sign() >= 0 {
value.SetUint64(0)
} else {
value.SetInt64(-1)
}
- stack.push(math.U256(value))
+ callContext.stack.push(math.U256(value))
return nil, nil
}
n := uint(shift.Uint64())
value.Rsh(value, n)
- stack.push(math.U256(value))
+ callContext.stack.push(math.U256(value))
return nil, nil
}
-func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- offset, size := stack.pop(), stack.pop()
- data := memory.Get(offset.Int64(), size.Int64())
- hash := crypto.Keccak256(data)
+func opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ offset, size := callContext.stack.pop(), callContext.stack.pop()
+ data := callContext.memory.GetPtr(offset.Int64(), size.Int64())
- if evm.vmConfig.EnablePreimageRecording {
- evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
- }
- stack.push(evm.interpreter.intPool.get().SetBytes(hash))
-
- evm.interpreter.intPool.put(offset, size)
- return nil, nil
-}
-
-func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(contract.Address().Big())
- return nil, nil
-}
-
-func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- slot := stack.peek()
- slot.Set(evm.StateDB.GetBalance(common.BigToAddress(slot)))
- return nil, nil
-}
-
-func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.Origin.Big())
- return nil, nil
-}
-
-func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(contract.Caller().Big())
- return nil, nil
-}
-
-func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().Set(contract.value))
- return nil, nil
-}
-
-func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32)))
- return nil, nil
-}
-
-func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
- return nil, nil
-}
-
-func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- var (
- memOffset = stack.pop()
- dataOffset = stack.pop()
- length = stack.pop()
- )
- memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length))
-
- evm.interpreter.intPool.put(memOffset, dataOffset, length)
- return nil, nil
-}
-
-func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData))))
- return nil, nil
-}
-
-func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- var (
- memOffset = stack.pop()
- dataOffset = stack.pop()
- length = stack.pop()
-
- end = evm.interpreter.intPool.get().Add(dataOffset, length)
- )
- defer evm.interpreter.intPool.put(memOffset, dataOffset, length, end)
-
- if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() {
- return nil, errReturnDataOutOfBounds
- }
- memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()])
-
- return nil, nil
-}
-
-func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- slot := stack.peek()
- slot.SetUint64(uint64(evm.StateDB.GetCodeSize(common.BigToAddress(slot))))
-
- return nil, nil
-}
-
-func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
- stack.push(l)
-
- return nil, nil
-}
-
-func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- var (
- memOffset = stack.pop()
- codeOffset = stack.pop()
- length = stack.pop()
- )
- codeCopy := getDataBig(contract.Code, codeOffset, length)
- memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
-
- evm.interpreter.intPool.put(memOffset, codeOffset, length)
- return nil, nil
-}
-
-func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- var (
- addr = common.BigToAddress(stack.pop())
- memOffset = stack.pop()
- codeOffset = stack.pop()
- length = stack.pop()
- )
- codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length)
- memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
-
- evm.interpreter.intPool.put(memOffset, codeOffset, length)
- return nil, nil
-}
-
-func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
- return nil, nil
-}
-
-func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- num := stack.pop()
-
- n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
- if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
- stack.push(evm.GetHash(num.Uint64()).Big())
+ if interpreter.hasher == nil {
+ interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState)
} else {
- stack.push(evm.interpreter.intPool.getZero())
+ interpreter.hasher.Reset()
}
- evm.interpreter.intPool.put(num, n)
+ interpreter.hasher.Write(data)
+ interpreter.hasher.Read(interpreter.hasherBuf[:])
+
+ evm := interpreter.evm
+ if evm.vmConfig.EnablePreimageRecording {
+ evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
+ }
+ callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.hasherBuf[:]))
+
+ interpreter.intPool.put(offset, size)
return nil, nil
}
-func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.Coinbase.Big())
+func opAddress(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetBytes(callContext.contract.Address().Bytes()))
return nil, nil
}
-func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Time)))
+func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ slot := callContext.stack.peek()
+ slot.Set(interpreter.evm.StateDB.GetBalance(common.BigToAddress(slot)))
return nil, nil
}
-func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockNumber)))
+func opOrigin(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Origin.Bytes()))
return nil, nil
}
-func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Difficulty)))
+func opCaller(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetBytes(callContext.contract.Caller().Bytes()))
return nil, nil
}
-func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(math.U256(evm.interpreter.intPool.get().SetUint64(evm.GasLimit)))
+func opCallValue(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().Set(callContext.contract.value))
return nil, nil
}
-func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- evm.interpreter.intPool.put(stack.pop())
+func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetBytes(getDataBig(callContext.contract.Input, callContext.stack.pop(), big32)))
return nil, nil
}
-func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- offset := stack.pop()
- val := evm.interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32))
- stack.push(val)
-
- evm.interpreter.intPool.put(offset)
+func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetInt64(int64(len(callContext.contract.Input))))
return nil, nil
}
-func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ memOffset = callContext.stack.pop()
+ dataOffset = callContext.stack.pop()
+ length = callContext.stack.pop()
+ )
+ callContext.memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(callContext.contract.Input, dataOffset, length))
+
+ interpreter.intPool.put(memOffset, dataOffset, length)
+ return nil, nil
+}
+
+func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(uint64(len(interpreter.returnData))))
+ return nil, nil
+}
+
+func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ memOffset = callContext.stack.pop()
+ dataOffset = callContext.stack.pop()
+ length = callContext.stack.pop()
+
+ end = interpreter.intPool.get().Add(dataOffset, length)
+ )
+ defer interpreter.intPool.put(memOffset, dataOffset, length, end)
+
+ if !end.IsUint64() || uint64(len(interpreter.returnData)) < end.Uint64() {
+ return nil, ErrReturnDataOutOfBounds
+ }
+ callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[dataOffset.Uint64():end.Uint64()])
+
+ return nil, nil
+}
+
+func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ slot := callContext.stack.peek()
+ slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot))))
+
+ return nil, nil
+}
+
+func opCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ l := interpreter.intPool.get().SetInt64(int64(len(callContext.contract.Code)))
+ callContext.stack.push(l)
+
+ return nil, nil
+}
+
+func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ memOffset = callContext.stack.pop()
+ codeOffset = callContext.stack.pop()
+ length = callContext.stack.pop()
+ )
+ codeCopy := getDataBig(callContext.contract.Code, codeOffset, length)
+ callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
+
+ interpreter.intPool.put(memOffset, codeOffset, length)
+ return nil, nil
+}
+
+func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ addr = common.BigToAddress(callContext.stack.pop())
+ memOffset = callContext.stack.pop()
+ codeOffset = callContext.stack.pop()
+ length = callContext.stack.pop()
+ )
+ codeCopy := getDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length)
+ callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
+
+ interpreter.intPool.put(memOffset, codeOffset, length)
+ return nil, nil
+}
+
+// opExtCodeHash returns the code hash of a specified account.
+// There are several cases when the function is called, while we can relay everything
+// to `state.GetCodeHash` function to ensure the correctness.
+// (1) Caller tries to get the code hash of a normal contract account, state
+// should return the relative code hash and set it as the result.
+//
+// (2) Caller tries to get the code hash of a non-existent account, state should
+// return common.Hash{} and zero will be set as the result.
+//
+// (3) Caller tries to get the code hash for an account without contract code,
+// state should return emptyCodeHash(0xc5d246...) as the result.
+//
+// (4) Caller tries to get the code hash of a precompiled account, the result
+// should be zero or emptyCodeHash.
+//
+// It is worth noting that in order to avoid unnecessary create and clean,
+// all precompile accounts on mainnet have been transferred 1 wei, so the return
+// here should be emptyCodeHash.
+// If the precompile account is not transferred any amount on a private or
+// customized chain, the return value will be zero.
+//
+// (5) Caller tries to get the code hash for an account which is marked as suicided
+// in the current transaction, the code hash of this account should be returned.
+//
+// (6) Caller tries to get the code hash for an account which is marked as deleted,
+// this account should be regarded as a non-existent account and zero should be returned.
+func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ slot := callContext.stack.peek()
+ address := common.BigToAddress(slot)
+ if interpreter.evm.StateDB.Empty(address) {
+ slot.SetUint64(0)
+ } else {
+ slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
+ }
+ return nil, nil
+}
+
+func opGasprice(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice))
+ return nil, nil
+}
+
+func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ num := callContext.stack.pop()
+
+ n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257)
+ if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 {
+ callContext.stack.push(interpreter.evm.GetHash(num.Uint64()).Big())
+ } else {
+ callContext.stack.push(interpreter.intPool.getZero())
+ }
+ interpreter.intPool.put(num, n)
+ return nil, nil
+}
+
+func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Coinbase.Bytes()))
+ return nil, nil
+}
+
+func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time)))
+ return nil, nil
+}
+
+func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber)))
+ return nil, nil
+}
+
+func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty)))
+ return nil, nil
+}
+
+func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit)))
+ return nil, nil
+}
+
+func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ interpreter.intPool.putOne(callContext.stack.pop())
+ return nil, nil
+}
+
+func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ v := callContext.stack.peek()
+ offset := v.Int64()
+ v.SetBytes(callContext.memory.GetPtr(offset, 32))
+ return nil, nil
+}
+
+func opMstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// pop value of the stack
- mStart, val := stack.pop(), stack.pop()
- memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
+ mStart, val := callContext.stack.pop(), callContext.stack.pop()
+ callContext.memory.Set32(mStart.Uint64(), val)
- evm.interpreter.intPool.put(mStart, val)
+ interpreter.intPool.put(mStart, val)
return nil, nil
}
-func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- off, val := stack.pop().Int64(), stack.pop().Int64()
- memory.store[off] = byte(val & 0xff)
+func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ off, val := callContext.stack.pop().Int64(), callContext.stack.pop().Int64()
+ callContext.memory.store[off] = byte(val & 0xff)
return nil, nil
}
-func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- loc := common.BigToHash(stack.pop())
- val := evm.StateDB.GetState(contract.Address(), loc).Big()
- stack.push(val)
+func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ loc := callContext.stack.peek()
+ val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), common.BigToHash(loc))
+ loc.SetBytes(val.Bytes())
return nil, nil
}
-func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- loc := common.BigToHash(stack.pop())
- val := stack.pop()
- evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
+func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ loc := common.BigToHash(callContext.stack.pop())
+ val := callContext.stack.pop()
+ interpreter.evm.StateDB.SetState(callContext.contract.Address(), loc, common.BigToHash(val))
- evm.interpreter.intPool.put(val)
+ interpreter.intPool.putOne(val)
return nil, nil
}
-func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- pos := stack.pop()
- if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
- nop := contract.GetOp(pos.Uint64())
- return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
+func opJump(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ pos := callContext.stack.pop()
+ if !callContext.contract.validJumpdest(pos) {
+ return nil, ErrInvalidJump
}
*pc = pos.Uint64()
- evm.interpreter.intPool.put(pos)
+ interpreter.intPool.putOne(pos)
return nil, nil
}
-func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- pos, cond := stack.pop(), stack.pop()
+func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ pos, cond := callContext.stack.pop(), callContext.stack.pop()
if cond.Sign() != 0 {
- if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
- nop := contract.GetOp(pos.Uint64())
- return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
+ if !callContext.contract.validJumpdest(pos) {
+ return nil, ErrInvalidJump
}
*pc = pos.Uint64()
} else {
*pc++
}
- evm.interpreter.intPool.put(pos, cond)
+ interpreter.intPool.put(pos, cond)
return nil, nil
}
-func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
return nil, nil
}
-func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
+func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(*pc))
return nil, nil
}
-func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
+func opMsize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetInt64(int64(callContext.memory.Len())))
return nil, nil
}
-func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
+func opGas(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(callContext.contract.Gas))
return nil, nil
}
-func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
var (
- value = stack.pop()
- offset, size = stack.pop(), stack.pop()
- input = memory.Get(offset.Int64(), size.Int64())
- gas = contract.Gas
+ value = callContext.stack.pop()
+ offset, size = callContext.stack.pop(), callContext.stack.pop()
+ input = callContext.memory.GetCopy(offset.Int64(), size.Int64())
+ gas = callContext.contract.Gas
)
- if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
+ if interpreter.evm.chainRules.IsEIP150 {
gas -= gas / 64
}
- contract.UseGas(gas)
- res, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
+ callContext.contract.UseGas(gas)
+ res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, value)
// Push item on the stack based on the returned error. If the ruleset is
// homestead we must check for CodeStoreOutOfGasError (homestead only
// rule) and treat as an error, if the ruleset is frontier we must
// ignore this error and pretend the operation was successful.
- if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
- stack.push(evm.interpreter.intPool.getZero())
+ if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
+ callContext.stack.push(interpreter.intPool.getZero())
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
- stack.push(evm.interpreter.intPool.getZero())
+ callContext.stack.push(interpreter.intPool.getZero())
} else {
- stack.push(addr.Big())
+ callContext.stack.push(interpreter.intPool.get().SetBytes(addr.Bytes()))
}
- contract.Gas += returnGas
- evm.interpreter.intPool.put(value, offset, size)
+ callContext.contract.Gas += returnGas
+ interpreter.intPool.put(value, offset, size)
- if suberr == errExecutionReverted {
+ if suberr == ErrExecutionReverted {
return res, nil
}
return nil, nil
}
-func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- // Pop gas. The actual gas in in evm.callGasTemp.
- evm.interpreter.intPool.put(stack.pop())
- gas := evm.callGasTemp
- // Pop other call parameters.
- addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
- toAddr := common.BigToAddress(addr)
- value = math.U256(value)
- // Get the arguments from the memory.
- args := memory.Get(inOffset.Int64(), inSize.Int64())
+func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ endowment = callContext.stack.pop()
+ offset, size = callContext.stack.pop(), callContext.stack.pop()
+ salt = callContext.stack.pop()
+ input = callContext.memory.GetCopy(offset.Int64(), size.Int64())
+ gas = callContext.contract.Gas
+ )
- if value.Sign() != 0 {
- gas += params.CallStipend
- }
- ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value)
- if err != nil {
- stack.push(evm.interpreter.intPool.getZero())
+ // Apply EIP150
+ gas -= gas / 64
+ callContext.contract.UseGas(gas)
+ res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas, endowment, salt)
+ // Push item on the stack based on the returned error.
+ if suberr != nil {
+ callContext.stack.push(interpreter.intPool.getZero())
} else {
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
+ callContext.stack.push(interpreter.intPool.get().SetBytes(addr.Bytes()))
}
- if err == nil || err == errExecutionReverted {
- memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
+ callContext.contract.Gas += returnGas
+ interpreter.intPool.put(endowment, offset, size, salt)
+
+ if suberr == ErrExecutionReverted {
+ return res, nil
}
- contract.Gas += returnGas
-
- evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
- return ret, nil
-}
-
-func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- // Pop gas. The actual gas is in evm.callGasTemp.
- evm.interpreter.intPool.put(stack.pop())
- gas := evm.callGasTemp
- // Pop other call parameters.
- addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
- toAddr := common.BigToAddress(addr)
- value = math.U256(value)
- // Get arguments from the memory.
- args := memory.Get(inOffset.Int64(), inSize.Int64())
-
- if value.Sign() != 0 {
- gas += params.CallStipend
- }
- ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value)
- if err != nil {
- stack.push(evm.interpreter.intPool.getZero())
- } else {
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
- }
- if err == nil || err == errExecutionReverted {
- memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
- }
- contract.Gas += returnGas
-
- evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
- return ret, nil
-}
-
-func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- // Pop gas. The actual gas is in evm.callGasTemp.
- evm.interpreter.intPool.put(stack.pop())
- gas := evm.callGasTemp
- // Pop other call parameters.
- addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
- toAddr := common.BigToAddress(addr)
- // Get arguments from the memory.
- args := memory.Get(inOffset.Int64(), inSize.Int64())
-
- ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
- if err != nil {
- stack.push(evm.interpreter.intPool.getZero())
- } else {
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
- }
- if err == nil || err == errExecutionReverted {
- memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
- }
- contract.Gas += returnGas
-
- evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
- return ret, nil
-}
-
-func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- // Pop gas. The actual gas is in evm.callGasTemp.
- evm.interpreter.intPool.put(stack.pop())
- gas := evm.callGasTemp
- // Pop other call parameters.
- addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
- toAddr := common.BigToAddress(addr)
- // Get arguments from the memory.
- args := memory.Get(inOffset.Int64(), inSize.Int64())
-
- ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas)
- if err != nil {
- stack.push(evm.interpreter.intPool.getZero())
- } else {
- stack.push(evm.interpreter.intPool.get().SetUint64(1))
- }
- if err == nil || err == errExecutionReverted {
- memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
- }
- contract.Gas += returnGas
-
- evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
- return ret, nil
-}
-
-func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- offset, size := stack.pop(), stack.pop()
- ret := memory.GetPtr(offset.Int64(), size.Int64())
-
- evm.interpreter.intPool.put(offset, size)
- return ret, nil
-}
-
-func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- offset, size := stack.pop(), stack.pop()
- ret := memory.GetPtr(offset.Int64(), size.Int64())
-
- evm.interpreter.intPool.put(offset, size)
- return ret, nil
-}
-
-func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
return nil, nil
}
-func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- balance := evm.StateDB.GetBalance(contract.Address())
- evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
+func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ // Pop gas. The actual gas in interpreter.evm.callGasTemp.
+ interpreter.intPool.putOne(callContext.stack.pop())
+ gas := interpreter.evm.callGasTemp
+ // Pop other call parameters.
+ addr, value, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
+ toAddr := common.BigToAddress(addr)
+ value = math.U256(value)
+ // Get the arguments from the memory.
+ args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64())
- evm.StateDB.Suicide(contract.Address())
+ if value.Sign() != 0 {
+ gas += params.CallStipend
+ }
+ ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, value)
+ if err != nil {
+ callContext.stack.push(interpreter.intPool.getZero())
+ } else {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(1))
+ }
+ if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
+ callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
+ }
+ callContext.contract.Gas += returnGas
+
+ interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
+ return ret, nil
+}
+
+func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
+ interpreter.intPool.putOne(callContext.stack.pop())
+ gas := interpreter.evm.callGasTemp
+ // Pop other call parameters.
+ addr, value, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
+ toAddr := common.BigToAddress(addr)
+ value = math.U256(value)
+ // Get arguments from the memory.
+ args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64())
+
+ if value.Sign() != 0 {
+ gas += params.CallStipend
+ }
+ ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, value)
+ if err != nil {
+ callContext.stack.push(interpreter.intPool.getZero())
+ } else {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(1))
+ }
+ if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
+ callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
+ }
+ callContext.contract.Gas += returnGas
+
+ interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
+ return ret, nil
+}
+
+func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
+ interpreter.intPool.putOne(callContext.stack.pop())
+ gas := interpreter.evm.callGasTemp
+ // Pop other call parameters.
+ addr, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
+ toAddr := common.BigToAddress(addr)
+ // Get arguments from the memory.
+ args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64())
+
+ ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas)
+ if err != nil {
+ callContext.stack.push(interpreter.intPool.getZero())
+ } else {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(1))
+ }
+ if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
+ callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
+ }
+ callContext.contract.Gas += returnGas
+
+ interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
+ return ret, nil
+}
+
+func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
+ interpreter.intPool.putOne(callContext.stack.pop())
+ gas := interpreter.evm.callGasTemp
+ // Pop other call parameters.
+ addr, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop()
+ toAddr := common.BigToAddress(addr)
+ // Get arguments from the memory.
+ args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64())
+
+ ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas)
+ if err != nil {
+ callContext.stack.push(interpreter.intPool.getZero())
+ } else {
+ callContext.stack.push(interpreter.intPool.get().SetUint64(1))
+ }
+ if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
+ callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
+ }
+ callContext.contract.Gas += returnGas
+
+ interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
+ return ret, nil
+}
+
+func opReturn(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ offset, size := callContext.stack.pop(), callContext.stack.pop()
+ ret := callContext.memory.GetPtr(offset.Int64(), size.Int64())
+
+ interpreter.intPool.put(offset, size)
+ return ret, nil
+}
+
+func opRevert(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ offset, size := callContext.stack.pop(), callContext.stack.pop()
+ ret := callContext.memory.GetPtr(offset.Int64(), size.Int64())
+
+ interpreter.intPool.put(offset, size)
+ return ret, nil
+}
+
+func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ return nil, nil
+}
+
+func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ balance := interpreter.evm.StateDB.GetBalance(callContext.contract.Address())
+ interpreter.evm.StateDB.AddBalance(common.BigToAddress(callContext.stack.pop()), balance)
+
+ interpreter.evm.StateDB.Suicide(callContext.contract.Address())
return nil, nil
}
@@ -806,32 +885,47 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *
// make log instruction function
func makeLog(size int) executionFunc {
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
+ return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
topics := make([]common.Hash, size)
- mStart, mSize := stack.pop(), stack.pop()
+ mStart, mSize := callContext.stack.pop(), callContext.stack.pop()
for i := 0; i < size; i++ {
- topics[i] = common.BigToHash(stack.pop())
+ topics[i] = common.BigToHash(callContext.stack.pop())
}
- d := memory.Get(mStart.Int64(), mSize.Int64())
- evm.StateDB.AddLog(&types.Log{
- Address: contract.Address(),
+ d := callContext.memory.GetCopy(mStart.Int64(), mSize.Int64())
+ interpreter.evm.StateDB.AddLog(&types.Log{
+ Address: callContext.contract.Address(),
Topics: topics,
Data: d,
// This is a non-consensus field, but assigned here because
// core/state doesn't know the current block number.
- BlockNumber: evm.BlockNumber.Uint64(),
+ BlockNumber: interpreter.evm.BlockNumber.Uint64(),
})
- evm.interpreter.intPool.put(mStart, mSize)
+ interpreter.intPool.put(mStart, mSize)
return nil, nil
}
}
+// opPush1 is a specialized version of pushN
+func opPush1(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ var (
+ codeLen = uint64(len(callContext.contract.Code))
+ integer = interpreter.intPool.get()
+ )
+ *pc += 1
+ if *pc < codeLen {
+ callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc])))
+ } else {
+ callContext.stack.push(integer.SetUint64(0))
+ }
+ return nil, nil
+}
+
// make push instruction function
func makePush(size uint64, pushByteSize int) executionFunc {
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- codeLen := len(contract.Code)
+ return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ codeLen := len(callContext.contract.Code)
startMin := codeLen
if int(*pc+1) < startMin {
@@ -843,18 +937,18 @@ func makePush(size uint64, pushByteSize int) executionFunc {
endMin = startMin + pushByteSize
}
- integer := evm.interpreter.intPool.get()
- stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
+ integer := interpreter.intPool.get()
+ callContext.stack.push(integer.SetBytes(common.RightPadBytes(callContext.contract.Code[startMin:endMin], pushByteSize)))
*pc += size
return nil, nil
}
}
-// make push instruction function
+// make dup instruction function
func makeDup(size int64) executionFunc {
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.dup(evm.interpreter.intPool, int(size))
+ return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.dup(interpreter.intPool, int(size))
return nil, nil
}
}
@@ -862,9 +956,9 @@ func makeDup(size int64) executionFunc {
// make swap instruction function
func makeSwap(size int64) executionFunc {
// switch n + 1 otherwise n would be swapped with n
- size += 1
- return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
- stack.swap(int(size))
+ size++
+ return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
+ callContext.stack.swap(int(size))
return nil, nil
}
}
diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go
index 0de558612c..61781b69a6 100644
--- a/core/vm/instructions_test.go
+++ b/core/vm/instructions_test.go
@@ -17,92 +17,142 @@
package vm
import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
-type twoOperandTest struct {
- x string
- y string
- expected string
+type TwoOperandTestcase struct {
+ X string
+ Y string
+ Expected string
}
-func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) {
+type twoOperandParams struct {
+ x string
+ y string
+}
+
+var commonParams []*twoOperandParams
+var twoOpMethods map[string]executionFunc
+
+func init() {
+
+ // Params is a list of common edgecases that should be used for some common tests
+ params := []string{
+ "0000000000000000000000000000000000000000000000000000000000000000", // 0
+ "0000000000000000000000000000000000000000000000000000000000000001", // +1
+ "0000000000000000000000000000000000000000000000000000000000000005", // +5
+ "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max
+ "8000000000000000000000000000000000000000000000000000000000000000", // - max
+ "8000000000000000000000000000000000000000000000000000000000000001", // - max+1
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1
+ }
+ // Params are combined so each param is used on each 'side'
+ commonParams = make([]*twoOperandParams, len(params)*len(params))
+ for i, x := range params {
+ for j, y := range params {
+ commonParams[i*len(params)+j] = &twoOperandParams{x, y}
+ }
+ }
+ twoOpMethods = map[string]executionFunc{
+ "add": opAdd,
+ "sub": opSub,
+ "mul": opMul,
+ "div": opDiv,
+ "sdiv": opSdiv,
+ "mod": opMod,
+ "smod": opSmod,
+ "exp": opExp,
+ "signext": opSignExtend,
+ "lt": opLt,
+ "gt": opGt,
+ "slt": opSlt,
+ "sgt": opSgt,
+ "eq": opEq,
+ "and": opAnd,
+ "or": opOr,
+ "xor": opXor,
+ "byte": opByte,
+ "shl": opSHL,
+ "shr": opSHR,
+ "sar": opSAR,
+ }
+}
+
+func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
+
var (
- env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
- stack = newstack()
- pc = uint64(0)
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ pc = uint64(0)
+ evmInterpreter = env.interpreter.(*EVMInterpreter)
)
+ // Stuff a couple of nonzero bigints into pool, to ensure that ops do not rely on pooled integers to be zero
+ evmInterpreter.intPool = poolOfIntPools.get()
+ evmInterpreter.intPool.put(big.NewInt(-1337))
+ evmInterpreter.intPool.put(big.NewInt(-1337))
+ evmInterpreter.intPool.put(big.NewInt(-1337))
+
for i, test := range tests {
- x := new(big.Int).SetBytes(common.Hex2Bytes(test.x))
- shift := new(big.Int).SetBytes(common.Hex2Bytes(test.y))
- expected := new(big.Int).SetBytes(common.Hex2Bytes(test.expected))
+ x := new(big.Int).SetBytes(common.Hex2Bytes(test.X))
+ y := new(big.Int).SetBytes(common.Hex2Bytes(test.Y))
+ expected := new(big.Int).SetBytes(common.Hex2Bytes(test.Expected))
stack.push(x)
- stack.push(shift)
- opFn(&pc, env, nil, nil, stack)
+ stack.push(y)
+ opFn(&pc, evmInterpreter, &callCtx{nil, stack, nil})
actual := stack.pop()
+
if actual.Cmp(expected) != 0 {
- t.Errorf("Testcase %d, expected %v, got %v", i, expected, actual)
+ t.Errorf("Testcase %v %d, %v(%x, %x): expected %x, got %x", name, i, name, x, y, expected, actual)
}
// Check pool usage
// 1.pool is not allowed to contain anything on the stack
// 2.pool is not allowed to contain the same pointers twice
- if env.interpreter.intPool.pool.len() > 0 {
+ if evmInterpreter.intPool.pool.len() > 0 {
poolvals := make(map[*big.Int]struct{})
poolvals[actual] = struct{}{}
- for env.interpreter.intPool.pool.len() > 0 {
- key := env.interpreter.intPool.get()
+ for evmInterpreter.intPool.pool.len() > 0 {
+ key := evmInterpreter.intPool.get()
if _, exist := poolvals[key]; exist {
- t.Errorf("Testcase %d, pool contains double-entry", i)
+ t.Errorf("Testcase %v %d, pool contains double-entry", name, i)
}
poolvals[key] = struct{}{}
}
}
}
+ poolOfIntPools.put(evmInterpreter.intPool)
}
func TestByteOp(t *testing.T) {
- var (
- env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
- stack = newstack()
- )
- tests := []struct {
- v string
- th uint64
- expected *big.Int
- }{
- {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 0, big.NewInt(0xAB)},
- {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 1, big.NewInt(0xCD)},
- {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 0, big.NewInt(0x00)},
- {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 1, big.NewInt(0xCD)},
- {"0000000000000000000000000000000000000000000000000000000000102030", 31, big.NewInt(0x30)},
- {"0000000000000000000000000000000000000000000000000000000000102030", 30, big.NewInt(0x20)},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32, big.NewInt(0x0)},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0xFFFFFFFFFFFFFFFF, big.NewInt(0x0)},
- }
- pc := uint64(0)
- for _, test := range tests {
- val := new(big.Int).SetBytes(common.Hex2Bytes(test.v))
- th := new(big.Int).SetUint64(test.th)
- stack.push(val)
- stack.push(th)
- opByte(&pc, env, nil, nil, stack)
- actual := stack.pop()
- if actual.Cmp(test.expected) != 0 {
- t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.v, test.th, test.expected, actual)
- }
+ tests := []TwoOperandTestcase{
+ {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"},
+ {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"},
+ {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"},
+ {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"},
+ {"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"},
+ {"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"},
+ {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"},
+ {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"},
}
+ testTwoOperandOp(t, tests, opByte, "byte")
}
func TestSHL(t *testing.T) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left
- tests := []twoOperandTest{
- {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
+ tests := []TwoOperandTestcase{
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"},
{"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
@@ -114,12 +164,12 @@ func TestSHL(t *testing.T) {
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},
}
- testTwoOperandOp(t, tests, opSHL)
+ testTwoOperandOp(t, tests, opSHL, "shl")
}
func TestSHR(t *testing.T) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
- tests := []twoOperandTest{
+ tests := []TwoOperandTestcase{
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"},
@@ -132,12 +182,12 @@ func TestSHR(t *testing.T) {
{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
}
- testTwoOperandOp(t, tests, opSHR)
+ testTwoOperandOp(t, tests, opSHR, "shr")
}
func TestSAR(t *testing.T) {
// Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right
- tests := []twoOperandTest{
+ tests := []TwoOperandTestcase{
{"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"},
{"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"},
{"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"},
@@ -156,51 +206,70 @@ func TestSAR(t *testing.T) {
{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"},
}
- testTwoOperandOp(t, tests, opSAR)
+ testTwoOperandOp(t, tests, opSAR, "sar")
}
-func TestSGT(t *testing.T) {
- tests := []twoOperandTest{
-
- {"0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"0000000000000000000000000000000000000000000000000000000000000001", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"0000000000000000000000000000000000000000000000000000000000000001", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"8000000000000000000000000000000000000000000000000000000000000001", "8000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"8000000000000000000000000000000000000000000000000000000000000001", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "8000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", "0000000000000000000000000000000000000000000000000000000000000000"},
- }
- testTwoOperandOp(t, tests, opSgt)
-}
-
-func TestSLT(t *testing.T) {
- tests := []twoOperandTest{
- {"0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"0000000000000000000000000000000000000000000000000000000000000001", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"0000000000000000000000000000000000000000000000000000000000000001", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"8000000000000000000000000000000000000000000000000000000000000001", "8000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"8000000000000000000000000000000000000000000000000000000000000001", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "8000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001"},
- {"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd", "0000000000000000000000000000000000000000000000000000000000000000"},
- {"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", "0000000000000000000000000000000000000000000000000000000000000001"},
- }
- testTwoOperandOp(t, tests, opSlt)
-}
-
-func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) {
+// getResult is a convenience function to generate the expected values
+func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
var (
- env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
- stack = newstack()
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ pc = uint64(0)
+ interpreter = env.interpreter.(*EVMInterpreter)
)
+ interpreter.intPool = poolOfIntPools.get()
+ result := make([]TwoOperandTestcase, len(args))
+ for i, param := range args {
+ x := new(big.Int).SetBytes(common.Hex2Bytes(param.x))
+ y := new(big.Int).SetBytes(common.Hex2Bytes(param.y))
+ stack.push(x)
+ stack.push(y)
+ opFn(&pc, interpreter, &callCtx{nil, stack, nil})
+ actual := stack.pop()
+ result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
+ }
+ return result
+}
+
+// utility function to fill the json-file with testcases
+// Enable this test to generate the 'testcases_xx.json' files
+func TestWriteExpectedValues(t *testing.T) {
+ t.Skip("Enable this test to create json test cases.")
+
+ for name, method := range twoOpMethods {
+ data, err := json.Marshal(getResult(commonParams, method))
+ if err != nil {
+ t.Fatal(err)
+ }
+ _ = ioutil.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+}
+
+// TestJsonTestcases runs through all the testcases defined as json-files
+func TestJsonTestcases(t *testing.T) {
+ for name := range twoOpMethods {
+ data, err := ioutil.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name))
+ if err != nil {
+ t.Fatal("Failed to read file", err)
+ }
+ var testcases []TwoOperandTestcase
+ json.Unmarshal(data, &testcases)
+ testTwoOperandOp(t, testcases, twoOpMethods[name], name)
+ }
+}
+
+func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
+ var (
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ )
+
+ env.interpreter = evmInterpreter
+ evmInterpreter.intPool = poolOfIntPools.get()
// convert args
byteArgs := make([][]byte, len(args))
for i, arg := range args {
@@ -213,9 +282,10 @@ func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contr
a := new(big.Int).SetBytes(arg)
stack.push(a)
}
- op(&pc, env, nil, nil, stack)
+ op(&pc, evmInterpreter, &callCtx{nil, stack, nil})
stack.pop()
}
+ poolOfIntPools.put(evmInterpreter.intPool)
}
func BenchmarkOpAdd64(b *testing.B) {
@@ -425,3 +495,148 @@ func BenchmarkOpIsZero(b *testing.B) {
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
opBenchmark(b, opIszero, x)
}
+
+func TestOpMstore(t *testing.T) {
+ var (
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ mem = NewMemory()
+ evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ )
+
+ env.interpreter = evmInterpreter
+ evmInterpreter.intPool = poolOfIntPools.get()
+ mem.Resize(64)
+ pc := uint64(0)
+ v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
+ stack.pushN(new(big.Int).SetBytes(common.Hex2Bytes(v)), big.NewInt(0))
+ opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
+ if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
+ t.Fatalf("Mstore fail, got %v, expected %v", got, v)
+ }
+ stack.pushN(big.NewInt(0x1), big.NewInt(0))
+ opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
+ if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
+ t.Fatalf("Mstore failed to overwrite previous value")
+ }
+ poolOfIntPools.put(evmInterpreter.intPool)
+}
+
+func BenchmarkOpMstore(bench *testing.B) {
+ var (
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ mem = NewMemory()
+ evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ )
+
+ env.interpreter = evmInterpreter
+ evmInterpreter.intPool = poolOfIntPools.get()
+ mem.Resize(64)
+ pc := uint64(0)
+ memStart := big.NewInt(0)
+ value := big.NewInt(0x1337)
+
+ bench.ResetTimer()
+ for i := 0; i < bench.N; i++ {
+ stack.pushN(value, memStart)
+ opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
+ }
+ poolOfIntPools.put(evmInterpreter.intPool)
+}
+
+func BenchmarkOpSHA3(bench *testing.B) {
+ var (
+ env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{})
+ stack = newstack()
+ mem = NewMemory()
+ evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ )
+ env.interpreter = evmInterpreter
+ evmInterpreter.intPool = poolOfIntPools.get()
+ mem.Resize(32)
+ pc := uint64(0)
+ start := big.NewInt(0)
+
+ bench.ResetTimer()
+ for i := 0; i < bench.N; i++ {
+ stack.pushN(big.NewInt(32), start)
+ opSha3(&pc, evmInterpreter, &callCtx{mem, stack, nil})
+ }
+ poolOfIntPools.put(evmInterpreter.intPool)
+}
+
+func TestCreate2Addreses(t *testing.T) {
+ type testcase struct {
+ origin string
+ salt string
+ code string
+ expected string
+ }
+
+ for i, tt := range []testcase{
+ {
+ origin: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000",
+ code: "0x00",
+ expected: "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38",
+ },
+ {
+ origin: "0xdeadbeef00000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000",
+ code: "0x00",
+ expected: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3",
+ },
+ {
+ origin: "0xdeadbeef00000000000000000000000000000000",
+ salt: "0xfeed000000000000000000000000000000000000",
+ code: "0x00",
+ expected: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833",
+ },
+ {
+ origin: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000",
+ code: "0xdeadbeef",
+ expected: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e",
+ },
+ {
+ origin: "0x00000000000000000000000000000000deadbeef",
+ salt: "0xcafebabe",
+ code: "0xdeadbeef",
+ expected: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7",
+ },
+ {
+ origin: "0x00000000000000000000000000000000deadbeef",
+ salt: "0xcafebabe",
+ code: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
+ expected: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C",
+ },
+ {
+ origin: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000",
+ code: "0x",
+ expected: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0",
+ },
+ } {
+
+ origin := common.BytesToAddress(common.FromHex(tt.origin))
+ salt := common.BytesToHash(common.FromHex(tt.salt))
+ code := common.FromHex(tt.code)
+ codeHash := crypto.Keccak256(code)
+ address := crypto.CreateAddress2(origin, salt, codeHash)
+ /*
+ stack := newstack()
+ // salt, but we don't need that for this test
+ stack.push(big.NewInt(int64(len(code)))) //size
+ stack.push(big.NewInt(0)) // memstart
+ stack.push(big.NewInt(0)) // value
+ gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0)
+ fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String())
+ */
+ expected := common.BytesToAddress(common.FromHex(tt.expected))
+ if !bytes.Equal(expected.Bytes(), address.Bytes()) {
+ t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String())
+ }
+
+ }
+}
diff --git a/core/vm/interface.go b/core/vm/interface.go
index 1ef91cf1d6..81549a9206 100644
--- a/core/vm/interface.go
+++ b/core/vm/interface.go
@@ -19,8 +19,8 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
// StateDB is an EVM database for full state querying.
@@ -40,8 +40,10 @@ type StateDB interface {
GetCodeSize(common.Address) int
AddRefund(uint64)
+ SubRefund(uint64)
GetRefund() uint64
+ GetCommittedState(common.Address, common.Hash) common.Hash
GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash)
@@ -61,10 +63,10 @@ type StateDB interface {
AddLog(*types.Log)
AddPreimage(common.Hash, []byte)
- ForEachStorage(common.Address, func(common.Hash, common.Hash) bool)
+ ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error
}
-// CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
+// CallContext provides a basic interface for the EVM calling conventions. The EVM
// depends on this context being implemented for doing subcalls and initialising new EVM contracts.
type CallContext interface {
// Call another contract
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 7090e0261f..2662a1922e 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -17,84 +17,118 @@
package vm
import (
- "fmt"
+ "hash"
"sync/atomic"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/log"
)
// Config are the configuration options for the Interpreter
type Config struct {
- // Debug enabled debugging Interpreter options
- Debug bool
- // Tracer is the op code logger
- Tracer Tracer
- // NoRecursion disabled Interpreter call, callcode,
- // delegate call and create.
- NoRecursion bool
- // Enable recording of SHA3/keccak preimages
- EnablePreimageRecording bool
- // JumpTable contains the EVM instruction table. This
- // may be left uninitialised and will be set to the default
- // table.
- JumpTable [256]operation
+ Debug bool // Enables debugging
+ Tracer Tracer // Opcode logger
+ NoRecursion bool // Disables call, callcode, delegate call and create
+ EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
+
+ JumpTable [256]operation // EVM instruction table, automatically populated if unset
+
+ EWASMInterpreter string // External EWASM interpreter options
+ EVMInterpreter string // External EVM interpreter options
+
+ ExtraEips []int // Additional EIPS that are to be enabled
}
// Interpreter is used to run Ethereum based contracts and will utilise the
// passed environment to query external sources for state information.
// The Interpreter will run the byte code VM based on the passed
// configuration.
-type Interpreter struct {
- evm *EVM
- cfg Config
- gasTable params.GasTable
- intPool *intPool
+type Interpreter interface {
+ // Run loops and evaluates the contract's code with the given input data and returns
+ // the return byte-slice and an error if one occurred.
+ Run(contract *Contract, input []byte, static bool) ([]byte, error)
+ // CanRun tells if the contract, passed as an argument, can be
+ // run by the current interpreter. This is meant so that the
+ // caller can do something like:
+ //
+ // ```golang
+ // for _, interpreter := range interpreters {
+ // if interpreter.CanRun(contract.code) {
+ // interpreter.Run(contract.code, input)
+ // }
+ // }
+ // ```
+ CanRun([]byte) bool
+}
+
+// callCtx contains the things that are per-call, such as stack and memory,
+// but not transients like pc and gas
+type callCtx struct {
+ memory *Memory
+ stack *Stack
+ contract *Contract
+}
+
+// keccakState wraps sha3.state. In addition to the usual hash methods, it also supports
+// Read to get a variable amount of data from the hash state. Read is faster than Sum
+// because it doesn't copy the internal state, but also modifies the internal state.
+type keccakState interface {
+ hash.Hash
+ Read([]byte) (int, error)
+}
+
+// EVMInterpreter represents an EVM interpreter
+type EVMInterpreter struct {
+ evm *EVM
+ cfg Config
+
+ intPool *intPool
+
+ hasher keccakState // Keccak256 hasher instance shared across opcodes
+ hasherBuf common.Hash // Keccak256 hasher result array shared aross opcodes
readOnly bool // Whether to throw on stateful modifications
returnData []byte // Last CALL's return data for subsequent reuse
}
-// NewInterpreter returns a new instance of the Interpreter.
-func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
+// NewEVMInterpreter returns a new instance of the Interpreter.
+func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
// We use the STOP instruction whether to see
// the jump table was initialised. If it was not
// we'll set the default jump table.
if !cfg.JumpTable[STOP].valid {
+ var jt JumpTable
switch {
- case evm.ChainConfig().IsConstantinople(evm.BlockNumber):
- cfg.JumpTable = constantinopleInstructionSet
- case evm.ChainConfig().IsByzantium(evm.BlockNumber):
- cfg.JumpTable = byzantiumInstructionSet
- case evm.ChainConfig().IsHomestead(evm.BlockNumber):
- cfg.JumpTable = homesteadInstructionSet
+ case evm.chainRules.IsIstanbul:
+ jt = istanbulInstructionSet
+ case evm.chainRules.IsConstantinople:
+ jt = constantinopleInstructionSet
+ case evm.chainRules.IsByzantium:
+ jt = byzantiumInstructionSet
+ case evm.chainRules.IsEIP158:
+ jt = spuriousDragonInstructionSet
+ case evm.chainRules.IsEIP150:
+ jt = tangerineWhistleInstructionSet
+ case evm.chainRules.IsHomestead:
+ jt = homesteadInstructionSet
default:
- cfg.JumpTable = frontierInstructionSet
+ jt = frontierInstructionSet
}
- }
-
- return &Interpreter{
- evm: evm,
- cfg: cfg,
- gasTable: evm.ChainConfig().GasTable(evm.BlockNumber),
- intPool: newIntPool(),
- }
-}
-
-func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error {
- if in.evm.chainRules.IsByzantium {
- if in.readOnly {
- // If the interpreter is operating in readonly mode, make sure no
- // state-modifying operation is performed. The 3rd stack item
- // for a call operation is the value. Transferring value from one
- // account to the others means the state is modified and should also
- // return with an error.
- if operation.writes || (op == CALL && stack.Back(2).BitLen() > 0) {
- return errWriteProtection
+ for i, eip := range cfg.ExtraEips {
+ if err := EnableEIP(eip, &jt); err != nil {
+ // Disable it, so caller can check if it's activated or not
+ cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...)
+ log.Error("EIP activation failed", "eip", eip, "error", err)
}
}
+ cfg.JumpTable = jt
+ }
+
+ return &EVMInterpreter{
+ evm: evm,
+ cfg: cfg,
}
- return nil
}
// Run loops and evaluates the contract's code with the given input data and returns
@@ -102,12 +136,27 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack
//
// It's important to note that any errors returned by the interpreter should be
// considered a revert-and-consume-all-gas operation except for
-// errExecutionReverted which means revert-and-keep-gas-left.
-func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) {
+// ErrExecutionReverted which means revert-and-keep-gas-left.
+func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) {
+ if in.intPool == nil {
+ in.intPool = poolOfIntPools.get()
+ defer func() {
+ poolOfIntPools.put(in.intPool)
+ in.intPool = nil
+ }()
+ }
+
// Increment the call depth which is restricted to 1024
in.evm.depth++
defer func() { in.evm.depth-- }()
+ // Make sure the readOnly is only set if we aren't in readOnly yet.
+ // This makes also sure that the readOnly flag isn't removed for child calls.
+ if readOnly && !in.readOnly {
+ in.readOnly = true
+ defer func() { in.readOnly = false }()
+ }
+
// Reset the previous call's return data. It's unimportant to preserve the old buffer
// as every returning call will return new data anyway.
in.returnData = nil
@@ -118,9 +167,14 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
}
var (
- op OpCode // current opcode
- mem = NewMemory() // bound memory
- stack = newstack() // local stack
+ op OpCode // current opcode
+ mem = NewMemory() // bound memory
+ stack = newstack() // local stack
+ callContext = &callCtx{
+ memory: mem,
+ stack: stack,
+ contract: contract,
+ }
// For optimisation reason we're using uint64 as the program counter.
// It's theoretically possible to go above 2^64. The YP defines the PC
// to be uint256. Practically much less so feasible.
@@ -130,9 +184,13 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
pcCopy uint64 // needed for the deferred Tracer
gasCopy uint64 // for Tracer to log gas remaining before execution
logged bool // deferred Tracer should ignore already logged steps
+ res []byte // result of the opcode execution function
)
contract.Input = input
+ // Reclaim the stack as an int pool when the execution stops
+ defer func() { in.intPool.put(stack.data...) }()
+
if in.cfg.Debug {
defer func() {
if err != nil {
@@ -148,7 +206,12 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
// the execution of one of the operations or until the done flag is set by the
// parent context.
- for atomic.LoadInt32(&in.evm.abort) == 0 {
+ steps := 0
+ for {
+ steps++
+ if steps%1000 == 0 && atomic.LoadInt32(&in.evm.abort) != 0 {
+ break
+ }
if in.cfg.Debug {
// Capture pre-execution values for tracing.
logged, pcCopy, gasCopy = false, pc, contract.Gas
@@ -159,35 +222,57 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
op = contract.GetOp(pc)
operation := in.cfg.JumpTable[op]
if !operation.valid {
- return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
+ return nil, &ErrInvalidOpCode{opcode: op}
}
- if err := operation.validateStack(stack); err != nil {
- return nil, err
+ // Validate stack
+ if sLen := stack.len(); sLen < operation.minStack {
+ return nil, &ErrStackUnderflow{stackLen: sLen, required: operation.minStack}
+ } else if sLen > operation.maxStack {
+ return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
}
// If the operation is valid, enforce and write restrictions
- if err := in.enforceRestrictions(op, operation, stack); err != nil {
- return nil, err
+ if in.readOnly && in.evm.chainRules.IsByzantium {
+ // If the interpreter is operating in readonly mode, make sure no
+ // state-modifying operation is performed. The 3rd stack item
+ // for a call operation is the value. Transferring value from one
+ // account to the others means the state is modified and should also
+ // return with an error.
+ if operation.writes || (op == CALL && stack.Back(2).Sign() != 0) {
+ return nil, ErrWriteProtection
+ }
+ }
+ // Static portion of gas
+ cost = operation.constantGas // For tracing
+ if !contract.UseGas(operation.constantGas) {
+ return nil, ErrOutOfGas
}
var memorySize uint64
// calculate the new memory size and expand the memory to fit
// the operation
+ // Memory check needs to be done prior to evaluating the dynamic gas portion,
+ // to detect calculation overflows
if operation.memorySize != nil {
- memSize, overflow := bigUint64(operation.memorySize(stack))
+ memSize, overflow := operation.memorySize(stack)
if overflow {
- return nil, errGasUintOverflow
+ return nil, ErrGasUintOverflow
}
// memory is expanded in words of 32 bytes. Gas
// is also calculated in words.
if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow {
- return nil, errGasUintOverflow
+ return nil, ErrGasUintOverflow
}
}
+ // Dynamic portion of gas
// consume the gas and return an error if not enough gas is available.
// cost is explicitly set so that the capture state defer method can get the proper cost
- cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize)
- if err != nil || !contract.UseGas(cost) {
- return nil, ErrOutOfGas
+ if operation.dynamicGas != nil {
+ var dynamicCost uint64
+ dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize)
+ cost += dynamicCost // total cost, for debug tracing
+ if err != nil || !contract.UseGas(dynamicCost) {
+ return nil, ErrOutOfGas
+ }
}
if memorySize > 0 {
mem.Resize(memorySize)
@@ -199,7 +284,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
}
// execute the operation
- res, err := operation.execute(&pc, in.evm, contract, mem, stack)
+ res, err = operation.execute(&pc, in, callContext)
// verifyPool is a build flag. Pool verification makes sure the integrity
// of the integer pool by comparing values to a default value.
if verifyPool {
@@ -210,12 +295,12 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
if operation.returns {
in.returnData = res
}
-
switch {
case err != nil:
return nil, err
case operation.reverts:
- return res, errExecutionReverted
+ log.Debug("ErrExecutionReverted", "pc", pc, "reverts", operation.reverts, "err", err)
+ return res, ErrExecutionReverted
case operation.halts:
return res, nil
case !operation.jumps:
@@ -224,3 +309,9 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
}
return nil, nil
}
+
+// CanRun tells if the contract, passed as an argument, can be
+// run by the current interpreter.
+func (in *EVMInterpreter) CanRun(code []byte) bool {
+ return true
+}
diff --git a/core/vm/intpool.go b/core/vm/intpool.go
index 5dbda18eee..eed074b073 100644
--- a/core/vm/intpool.go
+++ b/core/vm/intpool.go
@@ -16,7 +16,10 @@
package vm
-import "math/big"
+import (
+ "math/big"
+ "sync"
+)
var checkVal = big.NewInt(-42)
@@ -50,6 +53,17 @@ func (p *intPool) getZero() *big.Int {
return new(big.Int)
}
+// putOne returns an allocated big int to the pool to be later reused by get calls.
+// Note, the values as saved as is; neither put nor get zeroes the ints out!
+// As opposed to 'put' with variadic args, this method becomes inlined by the
+// go compiler
+func (p *intPool) putOne(i *big.Int) {
+ if len(p.pool.data) > poolLimit {
+ return
+ }
+ p.pool.push(i)
+}
+
// put returns an allocated big int to the pool to be later reused by get calls.
// Note, the values as saved as is; neither put nor get zeroes the ints out!
func (p *intPool) put(is ...*big.Int) {
@@ -65,3 +79,39 @@ func (p *intPool) put(is ...*big.Int) {
p.pool.push(i)
}
}
+
+// The intPool pool's default capacity
+const poolDefaultCap = 25
+
+// intPoolPool manages a pool of intPools.
+type intPoolPool struct {
+ pools []*intPool
+ lock sync.Mutex
+}
+
+var poolOfIntPools = &intPoolPool{
+ pools: make([]*intPool, 0, poolDefaultCap),
+}
+
+// get is looking for an available pool to return.
+func (ipp *intPoolPool) get() *intPool {
+ ipp.lock.Lock()
+ defer ipp.lock.Unlock()
+
+ if len(poolOfIntPools.pools) > 0 {
+ ip := ipp.pools[len(ipp.pools)-1]
+ ipp.pools = ipp.pools[:len(ipp.pools)-1]
+ return ip
+ }
+ return newIntPool()
+}
+
+// put a pool that has been allocated with get.
+func (ipp *intPoolPool) put(ip *intPool) {
+ ipp.lock.Lock()
+ defer ipp.lock.Unlock()
+
+ if len(ipp.pools) < cap(ipp.pools) {
+ ipp.pools = append(ipp.pools, ip)
+ }
+}
diff --git a/core/vm/intpool_test.go b/core/vm/intpool_test.go
new file mode 100644
index 0000000000..6c0d00f3ce
--- /dev/null
+++ b/core/vm/intpool_test.go
@@ -0,0 +1,55 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package vm
+
+import (
+ "testing"
+)
+
+func TestIntPoolPoolGet(t *testing.T) {
+ poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap)
+
+ nip := poolOfIntPools.get()
+ if nip == nil {
+ t.Fatalf("Invalid pool allocation")
+ }
+}
+
+func TestIntPoolPoolPut(t *testing.T) {
+ poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap)
+
+ nip := poolOfIntPools.get()
+ if len(poolOfIntPools.pools) != 0 {
+ t.Fatalf("Pool got added to list when none should have been")
+ }
+
+ poolOfIntPools.put(nip)
+ if len(poolOfIntPools.pools) == 0 {
+ t.Fatalf("Pool did not get added to list when one should have been")
+ }
+}
+
+func TestIntPoolPoolReUse(t *testing.T) {
+ poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap)
+ nip := poolOfIntPools.get()
+ poolOfIntPools.put(nip)
+ poolOfIntPools.get()
+
+ if len(poolOfIntPools.pools) != 0 {
+ t.Fatalf("Invalid number of pools. Got %d, expected %d", len(poolOfIntPools.pools), 0)
+ }
+}
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index 3389941353..b3a0f7ff7c 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -17,28 +17,27 @@
package vm
import (
- "errors"
- "math/big"
-
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
type (
- executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
- gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
- stackValidationFunc func(*Stack) error
- memorySizeFunc func(*Stack) *big.Int
+ executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error)
+ gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
+ // memorySizeFunc returns the required size, and whether the operation overflowed a uint64
+ memorySizeFunc func(*Stack) (size uint64, overflow bool)
)
-var errGasUintOverflow = errors.New("gas uint64 overflow")
-
type operation struct {
- // op is the operation function
- execute executionFunc
- // gasCost is the gas function and returns the gas required for execution
- gasCost gasFunc
- // validateStack validates the stack (size) for the operation
- validateStack stackValidationFunc
+ // execute is the operation function
+ execute executionFunc
+ constantGas uint64
+ dynamicGas gasFunc
+ // minStack tells how many stack items are required
+ minStack int
+ // maxStack specifies the max length the stack can have for this operation
+ // to not overflow the stack.
+ maxStack int
+
// memorySize returns the memory size required for the operation
memorySize memorySizeFunc
@@ -51,901 +50,1106 @@ type operation struct {
}
var (
- frontierInstructionSet = NewFrontierInstructionSet()
- homesteadInstructionSet = NewHomesteadInstructionSet()
- byzantiumInstructionSet = NewByzantiumInstructionSet()
- constantinopleInstructionSet = NewConstantinopleInstructionSet()
+ frontierInstructionSet = newFrontierInstructionSet()
+ homesteadInstructionSet = newHomesteadInstructionSet()
+ tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet()
+ spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
+ byzantiumInstructionSet = newByzantiumInstructionSet()
+ constantinopleInstructionSet = newConstantinopleInstructionSet()
+ istanbulInstructionSet = newIstanbulInstructionSet()
)
-// NewConstantinopleInstructionSet returns the frontier, homestead
+// JumpTable contains the EVM opcodes supported at a given fork.
+type JumpTable [256]operation
+
+// newIstanbulInstructionSet returns the frontier, homestead
+// byzantium, contantinople and petersburg instructions.
+func newIstanbulInstructionSet() JumpTable {
+ instructionSet := newConstantinopleInstructionSet()
+
+ enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344
+ enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
+ enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
+
+ return instructionSet
+}
+
+// newConstantinopleInstructionSet returns the frontier, homestead
// byzantium and contantinople instructions.
-func NewConstantinopleInstructionSet() [256]operation {
- // instructions that can be executed during the byzantium phase.
- instructionSet := NewByzantiumInstructionSet()
+func newConstantinopleInstructionSet() JumpTable {
+ instructionSet := newByzantiumInstructionSet()
instructionSet[SHL] = operation{
- execute: opSHL,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSHL,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
}
instructionSet[SHR] = operation{
- execute: opSHR,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSHR,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
}
instructionSet[SAR] = operation{
- execute: opSAR,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSAR,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ }
+ instructionSet[EXTCODEHASH] = operation{
+ execute: opExtCodeHash,
+ constantGas: params.ExtcodeHashGasConstantinople,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ }
+ instructionSet[CREATE2] = operation{
+ execute: opCreate2,
+ constantGas: params.Create2Gas,
+ dynamicGas: gasCreate2,
+ minStack: minStack(4, 1),
+ maxStack: maxStack(4, 1),
+ memorySize: memoryCreate2,
+ valid: true,
+ writes: true,
+ returns: true,
}
return instructionSet
}
-// NewByzantiumInstructionSet returns the frontier, homestead and
+// newByzantiumInstructionSet returns the frontier, homestead and
// byzantium instructions.
-func NewByzantiumInstructionSet() [256]operation {
- // instructions that can be executed during the homestead phase.
- instructionSet := NewHomesteadInstructionSet()
+func newByzantiumInstructionSet() JumpTable {
+ instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = operation{
- execute: opStaticCall,
- gasCost: gasStaticCall,
- validateStack: makeStackFunc(6, 1),
- memorySize: memoryStaticCall,
- valid: true,
- returns: true,
+ execute: opStaticCall,
+ constantGas: params.CallGasEIP150,
+ dynamicGas: gasStaticCall,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryStaticCall,
+ valid: true,
+ returns: true,
}
instructionSet[RETURNDATASIZE] = operation{
- execute: opReturnDataSize,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opReturnDataSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
}
instructionSet[RETURNDATACOPY] = operation{
- execute: opReturnDataCopy,
- gasCost: gasReturnDataCopy,
- validateStack: makeStackFunc(3, 0),
- memorySize: memoryReturnDataCopy,
- valid: true,
+ execute: opReturnDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasReturnDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryReturnDataCopy,
+ valid: true,
}
instructionSet[REVERT] = operation{
- execute: opRevert,
- gasCost: gasRevert,
- validateStack: makeStackFunc(2, 0),
- memorySize: memoryRevert,
- valid: true,
- reverts: true,
- returns: true,
+ execute: opRevert,
+ dynamicGas: gasRevert,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryRevert,
+ valid: true,
+ reverts: true,
+ returns: true,
}
return instructionSet
}
-// NewHomesteadInstructionSet returns the frontier and homestead
+// EIP 158 a.k.a Spurious Dragon
+func newSpuriousDragonInstructionSet() JumpTable {
+ instructionSet := newTangerineWhistleInstructionSet()
+ instructionSet[EXP].dynamicGas = gasExpEIP158
+ return instructionSet
+
+}
+
+// EIP 150 a.k.a Tangerine Whistle
+func newTangerineWhistleInstructionSet() JumpTable {
+ instructionSet := newHomesteadInstructionSet()
+ instructionSet[BALANCE].constantGas = params.BalanceGasEIP150
+ instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150
+ instructionSet[SLOAD].constantGas = params.SloadGasEIP150
+ instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150
+ instructionSet[CALL].constantGas = params.CallGasEIP150
+ instructionSet[CALLCODE].constantGas = params.CallGasEIP150
+ instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150
+ return instructionSet
+}
+
+// newHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase.
-func NewHomesteadInstructionSet() [256]operation {
- instructionSet := NewFrontierInstructionSet()
+func newHomesteadInstructionSet() JumpTable {
+ instructionSet := newFrontierInstructionSet()
instructionSet[DELEGATECALL] = operation{
- execute: opDelegateCall,
- gasCost: gasDelegateCall,
- validateStack: makeStackFunc(6, 1),
- memorySize: memoryDelegateCall,
- valid: true,
- returns: true,
+ execute: opDelegateCall,
+ dynamicGas: gasDelegateCall,
+ constantGas: params.CallGasFrontier,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryDelegateCall,
+ valid: true,
+ returns: true,
}
return instructionSet
}
-// NewFrontierInstructionSet returns the frontier instructions
+// newFrontierInstructionSet returns the frontier instructions
// that can be executed during the frontier phase.
-func NewFrontierInstructionSet() [256]operation {
- return [256]operation{
+func newFrontierInstructionSet() JumpTable {
+ return JumpTable{
STOP: {
- execute: opStop,
- gasCost: constGasFunc(0),
- validateStack: makeStackFunc(0, 0),
- halts: true,
- valid: true,
+ execute: opStop,
+ constantGas: 0,
+ minStack: minStack(0, 0),
+ maxStack: maxStack(0, 0),
+ halts: true,
+ valid: true,
},
ADD: {
- execute: opAdd,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opAdd,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
MUL: {
- execute: opMul,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opMul,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SUB: {
- execute: opSub,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSub,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
DIV: {
- execute: opDiv,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opDiv,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SDIV: {
- execute: opSdiv,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSdiv,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
MOD: {
- execute: opMod,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opMod,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SMOD: {
- execute: opSmod,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSmod,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
ADDMOD: {
- execute: opAddmod,
- gasCost: constGasFunc(GasMidStep),
- validateStack: makeStackFunc(3, 1),
- valid: true,
+ execute: opAddmod,
+ constantGas: GasMidStep,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ valid: true,
},
MULMOD: {
- execute: opMulmod,
- gasCost: constGasFunc(GasMidStep),
- validateStack: makeStackFunc(3, 1),
- valid: true,
+ execute: opMulmod,
+ constantGas: GasMidStep,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ valid: true,
},
EXP: {
- execute: opExp,
- gasCost: gasExp,
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opExp,
+ dynamicGas: gasExpFrontier,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SIGNEXTEND: {
- execute: opSignExtend,
- gasCost: constGasFunc(GasFastStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSignExtend,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
LT: {
- execute: opLt,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opLt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
GT: {
- execute: opGt,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opGt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SLT: {
- execute: opSlt,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSlt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SGT: {
- execute: opSgt,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opSgt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
EQ: {
- execute: opEq,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opEq,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
ISZERO: {
- execute: opIszero,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opIszero,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
AND: {
- execute: opAnd,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opAnd,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
XOR: {
- execute: opXor,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opXor,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
OR: {
- execute: opOr,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opOr,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
NOT: {
- execute: opNot,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opNot,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
BYTE: {
- execute: opByte,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(2, 1),
- valid: true,
+ execute: opByte,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
},
SHA3: {
- execute: opSha3,
- gasCost: gasSha3,
- validateStack: makeStackFunc(2, 1),
- memorySize: memorySha3,
- valid: true,
+ execute: opSha3,
+ constantGas: params.Sha3Gas,
+ dynamicGas: gasSha3,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ memorySize: memorySha3,
+ valid: true,
},
ADDRESS: {
- execute: opAddress,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opAddress,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
BALANCE: {
- execute: opBalance,
- gasCost: gasBalance,
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opBalance,
+ constantGas: params.BalanceGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
ORIGIN: {
- execute: opOrigin,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opOrigin,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
CALLER: {
- execute: opCaller,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opCaller,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
CALLVALUE: {
- execute: opCallValue,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opCallValue,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
CALLDATALOAD: {
- execute: opCallDataLoad,
- gasCost: constGasFunc(GasFastestStep),
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opCallDataLoad,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
CALLDATASIZE: {
- execute: opCallDataSize,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opCallDataSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
CALLDATACOPY: {
- execute: opCallDataCopy,
- gasCost: gasCallDataCopy,
- validateStack: makeStackFunc(3, 0),
- memorySize: memoryCallDataCopy,
- valid: true,
+ execute: opCallDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCallDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCallDataCopy,
+ valid: true,
},
CODESIZE: {
- execute: opCodeSize,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opCodeSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
CODECOPY: {
- execute: opCodeCopy,
- gasCost: gasCodeCopy,
- validateStack: makeStackFunc(3, 0),
- memorySize: memoryCodeCopy,
- valid: true,
+ execute: opCodeCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCodeCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCodeCopy,
+ valid: true,
},
GASPRICE: {
- execute: opGasprice,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opGasprice,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
EXTCODESIZE: {
- execute: opExtCodeSize,
- gasCost: gasExtCodeSize,
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opExtCodeSize,
+ constantGas: params.ExtcodeSizeGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
EXTCODECOPY: {
- execute: opExtCodeCopy,
- gasCost: gasExtCodeCopy,
- validateStack: makeStackFunc(4, 0),
- memorySize: memoryExtCodeCopy,
- valid: true,
+ execute: opExtCodeCopy,
+ constantGas: params.ExtcodeCopyBaseFrontier,
+ dynamicGas: gasExtCodeCopy,
+ minStack: minStack(4, 0),
+ maxStack: maxStack(4, 0),
+ memorySize: memoryExtCodeCopy,
+ valid: true,
},
BLOCKHASH: {
- execute: opBlockhash,
- gasCost: constGasFunc(GasExtStep),
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opBlockhash,
+ constantGas: GasExtStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
COINBASE: {
- execute: opCoinbase,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opCoinbase,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
TIMESTAMP: {
- execute: opTimestamp,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opTimestamp,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
NUMBER: {
- execute: opNumber,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opNumber,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
DIFFICULTY: {
- execute: opDifficulty,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opDifficulty,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
GASLIMIT: {
- execute: opGasLimit,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opGasLimit,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
POP: {
- execute: opPop,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(1, 0),
- valid: true,
+ execute: opPop,
+ constantGas: GasQuickStep,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ valid: true,
},
MLOAD: {
- execute: opMload,
- gasCost: gasMLoad,
- validateStack: makeStackFunc(1, 1),
- memorySize: memoryMLoad,
- valid: true,
+ execute: opMload,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMLoad,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ memorySize: memoryMLoad,
+ valid: true,
},
MSTORE: {
- execute: opMstore,
- gasCost: gasMStore,
- validateStack: makeStackFunc(2, 0),
- memorySize: memoryMStore,
- valid: true,
+ execute: opMstore,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryMStore,
+ valid: true,
},
MSTORE8: {
- execute: opMstore8,
- gasCost: gasMStore8,
- memorySize: memoryMStore8,
- validateStack: makeStackFunc(2, 0),
+ execute: opMstore8,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore8,
+ memorySize: memoryMStore8,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
valid: true,
},
SLOAD: {
- execute: opSload,
- gasCost: gasSLoad,
- validateStack: makeStackFunc(1, 1),
- valid: true,
+ execute: opSload,
+ constantGas: params.SloadGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
SSTORE: {
- execute: opSstore,
- gasCost: gasSStore,
- validateStack: makeStackFunc(2, 0),
- valid: true,
- writes: true,
+ execute: opSstore,
+ dynamicGas: gasSStore,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ valid: true,
+ writes: true,
},
JUMP: {
- execute: opJump,
- gasCost: constGasFunc(GasMidStep),
- validateStack: makeStackFunc(1, 0),
- jumps: true,
- valid: true,
+ execute: opJump,
+ constantGas: GasMidStep,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ jumps: true,
+ valid: true,
},
JUMPI: {
- execute: opJumpi,
- gasCost: constGasFunc(GasSlowStep),
- validateStack: makeStackFunc(2, 0),
- jumps: true,
- valid: true,
+ execute: opJumpi,
+ constantGas: GasSlowStep,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ jumps: true,
+ valid: true,
},
PC: {
- execute: opPc,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opPc,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
MSIZE: {
- execute: opMsize,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opMsize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
GAS: {
- execute: opGas,
- gasCost: constGasFunc(GasQuickStep),
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opGas,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
JUMPDEST: {
- execute: opJumpdest,
- gasCost: constGasFunc(params.JumpdestGas),
- validateStack: makeStackFunc(0, 0),
- valid: true,
+ execute: opJumpdest,
+ constantGas: params.JumpdestGas,
+ minStack: minStack(0, 0),
+ maxStack: maxStack(0, 0),
+ valid: true,
},
PUSH1: {
- execute: makePush(1, 1),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: opPush1,
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH2: {
- execute: makePush(2, 2),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(2, 2),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH3: {
- execute: makePush(3, 3),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(3, 3),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH4: {
- execute: makePush(4, 4),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(4, 4),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH5: {
- execute: makePush(5, 5),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(5, 5),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH6: {
- execute: makePush(6, 6),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(6, 6),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH7: {
- execute: makePush(7, 7),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(7, 7),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH8: {
- execute: makePush(8, 8),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(8, 8),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH9: {
- execute: makePush(9, 9),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(9, 9),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH10: {
- execute: makePush(10, 10),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(10, 10),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH11: {
- execute: makePush(11, 11),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(11, 11),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH12: {
- execute: makePush(12, 12),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(12, 12),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH13: {
- execute: makePush(13, 13),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(13, 13),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH14: {
- execute: makePush(14, 14),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(14, 14),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH15: {
- execute: makePush(15, 15),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(15, 15),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH16: {
- execute: makePush(16, 16),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(16, 16),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH17: {
- execute: makePush(17, 17),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(17, 17),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH18: {
- execute: makePush(18, 18),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(18, 18),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH19: {
- execute: makePush(19, 19),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(19, 19),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH20: {
- execute: makePush(20, 20),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(20, 20),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH21: {
- execute: makePush(21, 21),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(21, 21),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH22: {
- execute: makePush(22, 22),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(22, 22),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH23: {
- execute: makePush(23, 23),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(23, 23),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH24: {
- execute: makePush(24, 24),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(24, 24),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH25: {
- execute: makePush(25, 25),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(25, 25),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH26: {
- execute: makePush(26, 26),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(26, 26),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH27: {
- execute: makePush(27, 27),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(27, 27),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH28: {
- execute: makePush(28, 28),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(28, 28),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH29: {
- execute: makePush(29, 29),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(29, 29),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH30: {
- execute: makePush(30, 30),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(30, 30),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH31: {
- execute: makePush(31, 31),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(31, 31),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
PUSH32: {
- execute: makePush(32, 32),
- gasCost: gasPush,
- validateStack: makeStackFunc(0, 1),
- valid: true,
+ execute: makePush(32, 32),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
},
DUP1: {
- execute: makeDup(1),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(1),
- valid: true,
+ execute: makeDup(1),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(1),
+ maxStack: maxDupStack(1),
+ valid: true,
},
DUP2: {
- execute: makeDup(2),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(2),
- valid: true,
+ execute: makeDup(2),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(2),
+ maxStack: maxDupStack(2),
+ valid: true,
},
DUP3: {
- execute: makeDup(3),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(3),
- valid: true,
+ execute: makeDup(3),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(3),
+ maxStack: maxDupStack(3),
+ valid: true,
},
DUP4: {
- execute: makeDup(4),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(4),
- valid: true,
+ execute: makeDup(4),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(4),
+ maxStack: maxDupStack(4),
+ valid: true,
},
DUP5: {
- execute: makeDup(5),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(5),
- valid: true,
+ execute: makeDup(5),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(5),
+ maxStack: maxDupStack(5),
+ valid: true,
},
DUP6: {
- execute: makeDup(6),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(6),
- valid: true,
+ execute: makeDup(6),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(6),
+ maxStack: maxDupStack(6),
+ valid: true,
},
DUP7: {
- execute: makeDup(7),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(7),
- valid: true,
+ execute: makeDup(7),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(7),
+ maxStack: maxDupStack(7),
+ valid: true,
},
DUP8: {
- execute: makeDup(8),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(8),
- valid: true,
+ execute: makeDup(8),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(8),
+ maxStack: maxDupStack(8),
+ valid: true,
},
DUP9: {
- execute: makeDup(9),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(9),
- valid: true,
+ execute: makeDup(9),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(9),
+ maxStack: maxDupStack(9),
+ valid: true,
},
DUP10: {
- execute: makeDup(10),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(10),
- valid: true,
+ execute: makeDup(10),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(10),
+ maxStack: maxDupStack(10),
+ valid: true,
},
DUP11: {
- execute: makeDup(11),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(11),
- valid: true,
+ execute: makeDup(11),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(11),
+ maxStack: maxDupStack(11),
+ valid: true,
},
DUP12: {
- execute: makeDup(12),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(12),
- valid: true,
+ execute: makeDup(12),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(12),
+ maxStack: maxDupStack(12),
+ valid: true,
},
DUP13: {
- execute: makeDup(13),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(13),
- valid: true,
+ execute: makeDup(13),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(13),
+ maxStack: maxDupStack(13),
+ valid: true,
},
DUP14: {
- execute: makeDup(14),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(14),
- valid: true,
+ execute: makeDup(14),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(14),
+ maxStack: maxDupStack(14),
+ valid: true,
},
DUP15: {
- execute: makeDup(15),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(15),
- valid: true,
+ execute: makeDup(15),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(15),
+ maxStack: maxDupStack(15),
+ valid: true,
},
DUP16: {
- execute: makeDup(16),
- gasCost: gasDup,
- validateStack: makeDupStackFunc(16),
- valid: true,
+ execute: makeDup(16),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(16),
+ maxStack: maxDupStack(16),
+ valid: true,
},
SWAP1: {
- execute: makeSwap(1),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(2),
- valid: true,
+ execute: makeSwap(1),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(2),
+ maxStack: maxSwapStack(2),
+ valid: true,
},
SWAP2: {
- execute: makeSwap(2),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(3),
- valid: true,
+ execute: makeSwap(2),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(3),
+ maxStack: maxSwapStack(3),
+ valid: true,
},
SWAP3: {
- execute: makeSwap(3),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(4),
- valid: true,
+ execute: makeSwap(3),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(4),
+ maxStack: maxSwapStack(4),
+ valid: true,
},
SWAP4: {
- execute: makeSwap(4),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(5),
- valid: true,
+ execute: makeSwap(4),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(5),
+ maxStack: maxSwapStack(5),
+ valid: true,
},
SWAP5: {
- execute: makeSwap(5),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(6),
- valid: true,
+ execute: makeSwap(5),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(6),
+ maxStack: maxSwapStack(6),
+ valid: true,
},
SWAP6: {
- execute: makeSwap(6),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(7),
- valid: true,
+ execute: makeSwap(6),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(7),
+ maxStack: maxSwapStack(7),
+ valid: true,
},
SWAP7: {
- execute: makeSwap(7),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(8),
- valid: true,
+ execute: makeSwap(7),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(8),
+ maxStack: maxSwapStack(8),
+ valid: true,
},
SWAP8: {
- execute: makeSwap(8),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(9),
- valid: true,
+ execute: makeSwap(8),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(9),
+ maxStack: maxSwapStack(9),
+ valid: true,
},
SWAP9: {
- execute: makeSwap(9),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(10),
- valid: true,
+ execute: makeSwap(9),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(10),
+ maxStack: maxSwapStack(10),
+ valid: true,
},
SWAP10: {
- execute: makeSwap(10),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(11),
- valid: true,
+ execute: makeSwap(10),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(11),
+ maxStack: maxSwapStack(11),
+ valid: true,
},
SWAP11: {
- execute: makeSwap(11),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(12),
- valid: true,
+ execute: makeSwap(11),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(12),
+ maxStack: maxSwapStack(12),
+ valid: true,
},
SWAP12: {
- execute: makeSwap(12),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(13),
- valid: true,
+ execute: makeSwap(12),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(13),
+ maxStack: maxSwapStack(13),
+ valid: true,
},
SWAP13: {
- execute: makeSwap(13),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(14),
- valid: true,
+ execute: makeSwap(13),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(14),
+ maxStack: maxSwapStack(14),
+ valid: true,
},
SWAP14: {
- execute: makeSwap(14),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(15),
- valid: true,
+ execute: makeSwap(14),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(15),
+ maxStack: maxSwapStack(15),
+ valid: true,
},
SWAP15: {
- execute: makeSwap(15),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(16),
- valid: true,
+ execute: makeSwap(15),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(16),
+ maxStack: maxSwapStack(16),
+ valid: true,
},
SWAP16: {
- execute: makeSwap(16),
- gasCost: gasSwap,
- validateStack: makeSwapStackFunc(17),
- valid: true,
+ execute: makeSwap(16),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(17),
+ maxStack: maxSwapStack(17),
+ valid: true,
},
LOG0: {
- execute: makeLog(0),
- gasCost: makeGasLog(0),
- validateStack: makeStackFunc(2, 0),
- memorySize: memoryLog,
- valid: true,
- writes: true,
+ execute: makeLog(0),
+ dynamicGas: makeGasLog(0),
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
},
LOG1: {
- execute: makeLog(1),
- gasCost: makeGasLog(1),
- validateStack: makeStackFunc(3, 0),
- memorySize: memoryLog,
- valid: true,
- writes: true,
+ execute: makeLog(1),
+ dynamicGas: makeGasLog(1),
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
},
LOG2: {
- execute: makeLog(2),
- gasCost: makeGasLog(2),
- validateStack: makeStackFunc(4, 0),
- memorySize: memoryLog,
- valid: true,
- writes: true,
+ execute: makeLog(2),
+ dynamicGas: makeGasLog(2),
+ minStack: minStack(4, 0),
+ maxStack: maxStack(4, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
},
LOG3: {
- execute: makeLog(3),
- gasCost: makeGasLog(3),
- validateStack: makeStackFunc(5, 0),
- memorySize: memoryLog,
- valid: true,
- writes: true,
+ execute: makeLog(3),
+ dynamicGas: makeGasLog(3),
+ minStack: minStack(5, 0),
+ maxStack: maxStack(5, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
},
LOG4: {
- execute: makeLog(4),
- gasCost: makeGasLog(4),
- validateStack: makeStackFunc(6, 0),
- memorySize: memoryLog,
- valid: true,
- writes: true,
+ execute: makeLog(4),
+ dynamicGas: makeGasLog(4),
+ minStack: minStack(6, 0),
+ maxStack: maxStack(6, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
},
CREATE: {
- execute: opCreate,
- gasCost: gasCreate,
- validateStack: makeStackFunc(3, 1),
- memorySize: memoryCreate,
- valid: true,
- writes: true,
- returns: true,
+ execute: opCreate,
+ constantGas: params.CreateGas,
+ dynamicGas: gasCreate,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ memorySize: memoryCreate,
+ valid: true,
+ writes: true,
+ returns: true,
},
CALL: {
- execute: opCall,
- gasCost: gasCall,
- validateStack: makeStackFunc(7, 1),
- memorySize: memoryCall,
- valid: true,
- returns: true,
+ execute: opCall,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCall,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
},
CALLCODE: {
- execute: opCallCode,
- gasCost: gasCallCode,
- validateStack: makeStackFunc(7, 1),
- memorySize: memoryCall,
- valid: true,
- returns: true,
+ execute: opCallCode,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCallCode,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
},
RETURN: {
- execute: opReturn,
- gasCost: gasReturn,
- validateStack: makeStackFunc(2, 0),
- memorySize: memoryReturn,
- halts: true,
- valid: true,
+ execute: opReturn,
+ dynamicGas: gasReturn,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryReturn,
+ halts: true,
+ valid: true,
},
SELFDESTRUCT: {
- execute: opSuicide,
- gasCost: gasSuicide,
- validateStack: makeStackFunc(1, 0),
- halts: true,
- valid: true,
- writes: true,
+ execute: opSuicide,
+ dynamicGas: gasSelfdestruct,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ halts: true,
+ valid: true,
+ writes: true,
},
}
}
diff --git a/core/vm/logger.go b/core/vm/logger.go
index 4c820d8b53..970ff90fb3 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -18,22 +18,27 @@ package vm
import (
"encoding/hex"
+ "errors"
"fmt"
"io"
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
)
+var errTraceLimitReached = errors.New("the number of logs reached the specified limit")
+
+// Storage represents a contract's storage.
type Storage map[common.Hash]common.Hash
-func (self Storage) Copy() Storage {
+// Copy duplicates the current storage.
+func (s Storage) Copy() Storage {
cpy := make(Storage)
- for key, value := range self {
+ for key, value := range s {
cpy[key] = value
}
@@ -45,6 +50,7 @@ type LogConfig struct {
DisableMemory bool // disable memory capture
DisableStack bool // disable stack capture
DisableStorage bool // disable storage capture
+ Debug bool // print output during capture end
Limit int // maximum length of output, but zero means unlimited
}
@@ -53,16 +59,17 @@ type LogConfig struct {
// StructLog is emitted to the EVM each cycle and lists information about the current internal state
// prior to the execution of the statement.
type StructLog struct {
- Pc uint64 `json:"pc"`
- Op OpCode `json:"op"`
- Gas uint64 `json:"gas"`
- GasCost uint64 `json:"gasCost"`
- Memory []byte `json:"memory"`
- MemorySize int `json:"memSize"`
- Stack []*big.Int `json:"stack"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth int `json:"depth"`
- Err error `json:"-"`
+ Pc uint64 `json:"pc"`
+ Op OpCode `json:"op"`
+ Gas uint64 `json:"gas"`
+ GasCost uint64 `json:"gasCost"`
+ Memory []byte `json:"memory"`
+ MemorySize int `json:"memSize"`
+ Stack []*big.Int `json:"stack"`
+ Storage map[common.Hash]common.Hash `json:"-"`
+ Depth int `json:"depth"`
+ RefundCounter uint64 `json:"refund"`
+ Err error `json:"-"`
}
// overrides for gencodec
@@ -75,10 +82,12 @@ type structLogMarshaling struct {
ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON
}
+// OpName formats the operand name in a human-readable format.
func (s *StructLog) OpName() string {
return s.Op.String()
}
+// ErrorString formats the log's error as a string.
func (s *StructLog) ErrorString() string {
if s.Err != nil {
return s.Err.Error()
@@ -92,7 +101,7 @@ func (s *StructLog) ErrorString() string {
// Note that reference types are actual VM data structures; make copies
// if you need to retain them beyond the current call.
type Tracer interface {
- CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error
+ CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error
@@ -123,6 +132,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
return logger
}
+// CaptureStart implements the Tracer interface to initialize the tracing operation.
func (l *StructLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
return nil
}
@@ -133,7 +143,7 @@ func (l *StructLogger) CaptureStart(from common.Address, to common.Address, crea
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
// check if already accumulated the specified number of logs
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
- return ErrTraceLimitReached
+ return errTraceLimitReached
}
// initialise new changed values storage container for this contract
@@ -151,7 +161,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
)
l.changedValues[contract.Address()][address] = value
}
- // Copy a snapstot of the current memory state to a new buffer
+ // Copy a snapshot of the current memory state to a new buffer
var mem []byte
if !l.cfg.DisableMemory {
mem = make([]byte, len(memory.Data()))
@@ -170,20 +180,29 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
if !l.cfg.DisableStorage {
storage = l.changedValues[contract.Address()].Copy()
}
- // create a new snaptshot of the EVM.
- log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, err}
+ // create a new snapshot of the EVM.
+ log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, env.StateDB.GetRefund(), err}
l.logs = append(l.logs, log)
return nil
}
+// CaptureFault implements the Tracer interface to trace an execution fault
+// while running an opcode.
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
return nil
}
+// CaptureEnd is called after the call finishes to finalize the tracing.
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
l.output = output
l.err = err
+ if l.cfg.Debug {
+ fmt.Printf("0x%x\n", output)
+ if err != nil {
+ fmt.Printf(" error: %v\n", err)
+ }
+ }
return nil
}
diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go
new file mode 100644
index 0000000000..2eeba8dfac
--- /dev/null
+++ b/core/vm/logger_json.go
@@ -0,0 +1,87 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package vm
+
+import (
+ "encoding/json"
+ "io"
+ "math/big"
+ "time"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+)
+
+type JSONLogger struct {
+ encoder *json.Encoder
+ cfg *LogConfig
+}
+
+// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects
+// into the provided stream.
+func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger {
+ l := &JSONLogger{json.NewEncoder(writer), cfg}
+ if l.cfg == nil {
+ l.cfg = &LogConfig{}
+ }
+ return l
+}
+
+func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
+ return nil
+}
+
+// CaptureState outputs state information on the logger.
+func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
+ log := StructLog{
+ Pc: pc,
+ Op: op,
+ Gas: gas,
+ GasCost: cost,
+ MemorySize: memory.Len(),
+ Storage: nil,
+ Depth: depth,
+ RefundCounter: env.StateDB.GetRefund(),
+ Err: err,
+ }
+ if !l.cfg.DisableMemory {
+ log.Memory = memory.Data()
+ }
+ if !l.cfg.DisableStack {
+ log.Stack = stack.Data()
+ }
+ return l.encoder.Encode(log)
+}
+
+// CaptureFault outputs state information on the logger.
+func (l *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
+ return nil
+}
+
+// CaptureEnd is triggered at end of execution.
+func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
+ type endLog struct {
+ Output string `json:"output"`
+ GasUsed math.HexOrDecimal64 `json:"gasUsed"`
+ Time time.Duration `json:"time"`
+ Err string `json:"error,omitempty"`
+ }
+ if err != nil {
+ return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()})
+ }
+ return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""})
+}
diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go
index 28830c445c..e3e0a085b9 100644
--- a/core/vm/logger_test.go
+++ b/core/vm/logger_test.go
@@ -20,8 +20,10 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/params"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
)
type dummyContractRef struct {
@@ -41,14 +43,15 @@ func (d *dummyContractRef) SetBalance(*big.Int) {}
func (d *dummyContractRef) SetNonce(uint64) {}
func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) }
-type dummyStateDB struct {
- NoopStateDB
- ref *dummyContractRef
+type dummyStatedb struct {
+ state.StateDB
}
+func (*dummyStatedb) GetRefund() uint64 { return 1337 }
+
func TestStoreCapture(t *testing.T) {
var (
- env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
+ env = NewEVM(Context{}, &dummyStatedb{}, nil, params.TestChainConfig, Config{})
logger = NewStructLogger(nil)
mem = NewMemory()
stack = newstack()
@@ -56,9 +59,7 @@ func TestStoreCapture(t *testing.T) {
)
stack.push(big.NewInt(1))
stack.push(big.NewInt(0))
-
var index common.Hash
-
logger.CaptureState(env, 0, SSTORE, 0, 0, mem, stack, contract, 0, nil)
if len(logger.changedValues[contract.Address()]) == 0 {
t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(), len(logger.changedValues[contract.Address()]))
diff --git a/core/vm/memory.go b/core/vm/memory.go
index 99a84d2271..7fc44a0961 100644
--- a/core/vm/memory.go
+++ b/core/vm/memory.go
@@ -16,7 +16,12 @@
package vm
-import "fmt"
+import (
+ "fmt"
+ "math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+)
// Memory implements a simple memory model for the ethereum virtual machine.
type Memory struct {
@@ -24,25 +29,39 @@ type Memory struct {
lastGasCost uint64
}
+// NewMemory returns a new memory model.
func NewMemory() *Memory {
return &Memory{}
}
// Set sets offset + size to value
func (m *Memory) Set(offset, size uint64, value []byte) {
- // length of store may never be less than offset + size.
- // The store should be resized PRIOR to setting the memory
- if size > uint64(len(m.store)) {
- panic("INVALID memory: store empty")
- }
-
// It's possible the offset is greater than 0 and size equals 0. This is because
// the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP)
if size > 0 {
+ // length of store may never be less than offset + size.
+ // The store should be resized PRIOR to setting the memory
+ if offset+size > uint64(len(m.store)) {
+ panic("invalid memory: store empty")
+ }
copy(m.store[offset:offset+size], value)
}
}
+// Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to
+// 32 bytes.
+func (m *Memory) Set32(offset uint64, val *big.Int) {
+ // length of store may never be less than offset + size.
+ // The store should be resized PRIOR to setting the memory
+ if offset+32 > uint64(len(m.store)) {
+ panic("invalid memory: store empty")
+ }
+ // Zero the memory area
+ copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+ // Fill in relevant bits
+ math.ReadBits(val, m.store[offset:offset+32])
+}
+
// Resize resizes the memory to size
func (m *Memory) Resize(size uint64) {
if uint64(m.Len()) < size {
@@ -51,14 +70,14 @@ func (m *Memory) Resize(size uint64) {
}
// Get returns offset + size as a new slice
-func (self *Memory) Get(offset, size int64) (cpy []byte) {
+func (m *Memory) GetCopy(offset, size int64) (cpy []byte) {
if size == 0 {
return nil
}
- if len(self.store) > int(offset) {
+ if len(m.store) > int(offset) {
cpy = make([]byte, size)
- copy(cpy, self.store[offset:offset+size])
+ copy(cpy, m.store[offset:offset+size])
return
}
@@ -67,13 +86,13 @@ func (self *Memory) Get(offset, size int64) (cpy []byte) {
}
// GetPtr returns the offset + size
-func (self *Memory) GetPtr(offset, size int64) []byte {
+func (m *Memory) GetPtr(offset, size int64) []byte {
if size == 0 {
return nil
}
- if len(self.store) > int(offset) {
- return self.store[offset : offset+size]
+ if len(m.store) > int(offset) {
+ return m.store[offset : offset+size]
}
return nil
@@ -89,6 +108,7 @@ func (m *Memory) Data() []byte {
return m.store
}
+// Print dumps the content of the memory.
func (m *Memory) Print() {
fmt.Printf("### mem %d bytes ###\n", len(m.store))
if len(m.store) > 0 {
diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go
index bec0235bcc..4fcb41442c 100644
--- a/core/vm/memory_table.go
+++ b/core/vm/memory_table.go
@@ -16,84 +16,98 @@
package vm
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common/math"
-)
-
-func memorySha3(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(1))
+func memorySha3(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(1))
}
-func memoryCallDataCopy(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(2))
+func memoryCallDataCopy(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(2))
}
-func memoryReturnDataCopy(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(2))
+func memoryReturnDataCopy(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(2))
}
-func memoryCodeCopy(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(2))
+func memoryCodeCopy(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(2))
}
-func memoryExtCodeCopy(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(1), stack.Back(3))
+func memoryExtCodeCopy(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(1), stack.Back(3))
}
-func memoryMLoad(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), big.NewInt(32))
+func memoryMLoad(stack *Stack) (uint64, bool) {
+ return calcMemSize64WithUint(stack.Back(0), 32)
}
-func memoryMStore8(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), big.NewInt(1))
+func memoryMStore8(stack *Stack) (uint64, bool) {
+ return calcMemSize64WithUint(stack.Back(0), 1)
}
-func memoryMStore(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), big.NewInt(32))
+func memoryMStore(stack *Stack) (uint64, bool) {
+ return calcMemSize64WithUint(stack.Back(0), 32)
}
-func memoryCreate(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(1), stack.Back(2))
+func memoryCreate(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(1), stack.Back(2))
}
-func memoryCall(stack *Stack) *big.Int {
- x := calcMemSize(stack.Back(5), stack.Back(6))
- y := calcMemSize(stack.Back(3), stack.Back(4))
-
- return math.BigMax(x, y)
+func memoryCreate2(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(1), stack.Back(2))
}
-func memoryCallCode(stack *Stack) *big.Int {
- x := calcMemSize(stack.Back(5), stack.Back(6))
- y := calcMemSize(stack.Back(3), stack.Back(4))
-
- return math.BigMax(x, y)
+func memoryCall(stack *Stack) (uint64, bool) {
+ x, overflow := calcMemSize64(stack.Back(5), stack.Back(6))
+ if overflow {
+ return 0, true
+ }
+ y, overflow := calcMemSize64(stack.Back(3), stack.Back(4))
+ if overflow {
+ return 0, true
+ }
+ if x > y {
+ return x, false
+ }
+ return y, false
}
-func memoryDelegateCall(stack *Stack) *big.Int {
- x := calcMemSize(stack.Back(4), stack.Back(5))
- y := calcMemSize(stack.Back(2), stack.Back(3))
-
- return math.BigMax(x, y)
+func memoryDelegateCall(stack *Stack) (uint64, bool) {
+ x, overflow := calcMemSize64(stack.Back(4), stack.Back(5))
+ if overflow {
+ return 0, true
+ }
+ y, overflow := calcMemSize64(stack.Back(2), stack.Back(3))
+ if overflow {
+ return 0, true
+ }
+ if x > y {
+ return x, false
+ }
+ return y, false
}
-func memoryStaticCall(stack *Stack) *big.Int {
- x := calcMemSize(stack.Back(4), stack.Back(5))
- y := calcMemSize(stack.Back(2), stack.Back(3))
-
- return math.BigMax(x, y)
+func memoryStaticCall(stack *Stack) (uint64, bool) {
+ x, overflow := calcMemSize64(stack.Back(4), stack.Back(5))
+ if overflow {
+ return 0, true
+ }
+ y, overflow := calcMemSize64(stack.Back(2), stack.Back(3))
+ if overflow {
+ return 0, true
+ }
+ if x > y {
+ return x, false
+ }
+ return y, false
}
-func memoryReturn(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(1))
+func memoryReturn(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(1))
}
-func memoryRevert(stack *Stack) *big.Int {
- return calcMemSize(stack.Back(0), stack.Back(1))
+func memoryRevert(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(1))
}
-func memoryLog(stack *Stack) *big.Int {
- mSize, mStart := stack.Back(1), stack.Back(0)
- return calcMemSize(mStart, mSize)
+func memoryLog(stack *Stack) (uint64, bool) {
+ return calcMemSize64(stack.Back(0), stack.Back(1))
}
diff --git a/core/vm/noop.go b/core/vm/noop.go
deleted file mode 100644
index b71ead0d77..0000000000
--- a/core/vm/noop.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package vm
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-func NoopCanTransfer(db StateDB, from common.Address, balance *big.Int) bool {
- return true
-}
-func NoopTransfer(db StateDB, from, to common.Address, amount *big.Int) {}
-
-type NoopEVMCallContext struct{}
-
-func (NoopEVMCallContext) Call(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) {
- return nil, nil
-}
-func (NoopEVMCallContext) CallCode(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) {
- return nil, nil
-}
-func (NoopEVMCallContext) Create(caller ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) {
- return nil, common.Address{}, nil
-}
-func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) {
- return nil, nil
-}
-
-type NoopStateDB struct{}
-
-func (NoopStateDB) CreateAccount(common.Address) {}
-func (NoopStateDB) SubBalance(common.Address, *big.Int) {}
-func (NoopStateDB) AddBalance(common.Address, *big.Int) {}
-func (NoopStateDB) GetBalance(common.Address) *big.Int { return nil }
-func (NoopStateDB) GetNonce(common.Address) uint64 { return 0 }
-func (NoopStateDB) SetNonce(common.Address, uint64) {}
-func (NoopStateDB) GetCodeHash(common.Address) common.Hash { return common.Hash{} }
-func (NoopStateDB) GetCode(common.Address) []byte { return nil }
-func (NoopStateDB) SetCode(common.Address, []byte) {}
-func (NoopStateDB) GetCodeSize(common.Address) int { return 0 }
-func (NoopStateDB) AddRefund(uint64) {}
-func (NoopStateDB) GetRefund() uint64 { return 0 }
-func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} }
-func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {}
-func (NoopStateDB) Suicide(common.Address) bool { return false }
-func (NoopStateDB) HasSuicided(common.Address) bool { return false }
-func (NoopStateDB) Exist(common.Address) bool { return false }
-func (NoopStateDB) Empty(common.Address) bool { return false }
-func (NoopStateDB) RevertToSnapshot(int) {}
-func (NoopStateDB) Snapshot() int { return 0 }
-func (NoopStateDB) AddLog(*types.Log) {}
-func (NoopStateDB) AddPreimage(common.Hash, []byte) {}
-func (NoopStateDB) ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) {}
diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go
index 7fe55b72f6..322e01d17c 100644
--- a/core/vm/opcodes.go
+++ b/core/vm/opcodes.go
@@ -23,6 +23,7 @@ import (
// OpCode is an EVM opcode
type OpCode byte
+// IsPush specifies if an opcode is a PUSH opcode.
func (op OpCode) IsPush() bool {
switch op {
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
@@ -31,12 +32,13 @@ func (op OpCode) IsPush() bool {
return false
}
+// IsStaticJump specifies if an opcode is JUMP.
func (op OpCode) IsStaticJump() bool {
return op == JUMP
}
+// 0x0 range - arithmetic ops.
const (
- // 0x0 range - arithmetic ops
STOP OpCode = iota
ADD
MUL
@@ -51,6 +53,7 @@ const (
SIGNEXTEND
)
+// 0x10 range - comparison ops.
const (
LT OpCode = iota + 0x10
GT
@@ -67,11 +70,11 @@ const (
SHR
SAR
- SHA3 = 0x20
+ SHA3 OpCode = 0x20
)
+// 0x30 range - closure state.
const (
- // 0x30 range - closure state
ADDRESS OpCode = 0x30 + iota
BALANCE
ORIGIN
@@ -87,20 +90,23 @@ const (
EXTCODECOPY
RETURNDATASIZE
RETURNDATACOPY
+ EXTCODEHASH
)
+// 0x40 range - block operations.
const (
- // 0x40 range - block operations
BLOCKHASH OpCode = 0x40 + iota
COINBASE
TIMESTAMP
NUMBER
DIFFICULTY
GASLIMIT
+ CHAINID OpCode = 0x46
+ SELFBALANCE OpCode = 0x47
)
+// 0x50 range - 'storage' and execution.
const (
- // 0x50 range - 'storage' and execution
POP OpCode = 0x50 + iota
MLOAD
MSTORE
@@ -115,8 +121,8 @@ const (
JUMPDEST
)
+// 0x60 range.
const (
- // 0x60 range
PUSH1 OpCode = 0x60 + iota
PUSH2
PUSH3
@@ -183,6 +189,7 @@ const (
SWAP16
)
+// 0xa0 range - logging ops.
const (
LOG0 OpCode = 0xa0 + iota
LOG1
@@ -191,29 +198,29 @@ const (
LOG4
)
-// unofficial opcodes used for parsing
+// unofficial opcodes used for parsing.
const (
PUSH OpCode = 0xb0 + iota
DUP
SWAP
)
+// 0xf0 range - closures.
const (
- // 0xf0 range - closures
CREATE OpCode = 0xf0 + iota
CALL
CALLCODE
RETURN
DELEGATECALL
- STATICCALL = 0xfa
-
- REVERT = 0xfd
- SELFDESTRUCT = 0xff
+ CREATE2
+ STATICCALL OpCode = 0xfa
+ REVERT OpCode = 0xfd
+ SELFDESTRUCT OpCode = 0xff
)
-// Since the opcodes aren't all in order we can't use a regular slice
+// Since the opcodes aren't all in order we can't use a regular slice.
var opCodeToString = map[OpCode]string{
- // 0x0 range - arithmetic ops
+ // 0x0 range - arithmetic ops.
STOP: "STOP",
ADD: "ADD",
MUL: "MUL",
@@ -232,7 +239,7 @@ var opCodeToString = map[OpCode]string{
ISZERO: "ISZERO",
SIGNEXTEND: "SIGNEXTEND",
- // 0x10 range - bit ops
+ // 0x10 range - bit ops.
AND: "AND",
OR: "OR",
XOR: "XOR",
@@ -243,10 +250,10 @@ var opCodeToString = map[OpCode]string{
ADDMOD: "ADDMOD",
MULMOD: "MULMOD",
- // 0x20 range - crypto
+ // 0x20 range - crypto.
SHA3: "SHA3",
- // 0x30 range - closure state
+ // 0x30 range - closure state.
ADDRESS: "ADDRESS",
BALANCE: "BALANCE",
ORIGIN: "ORIGIN",
@@ -262,16 +269,19 @@ var opCodeToString = map[OpCode]string{
EXTCODECOPY: "EXTCODECOPY",
RETURNDATASIZE: "RETURNDATASIZE",
RETURNDATACOPY: "RETURNDATACOPY",
+ EXTCODEHASH: "EXTCODEHASH",
- // 0x40 range - block operations
- BLOCKHASH: "BLOCKHASH",
- COINBASE: "COINBASE",
- TIMESTAMP: "TIMESTAMP",
- NUMBER: "NUMBER",
- DIFFICULTY: "DIFFICULTY",
- GASLIMIT: "GASLIMIT",
+ // 0x40 range - block operations.
+ BLOCKHASH: "BLOCKHASH",
+ COINBASE: "COINBASE",
+ TIMESTAMP: "TIMESTAMP",
+ NUMBER: "NUMBER",
+ DIFFICULTY: "DIFFICULTY",
+ GASLIMIT: "GASLIMIT",
+ CHAINID: "CHAINID",
+ SELFBALANCE: "SELFBALANCE",
- // 0x50 range - 'storage' and execution
+ // 0x50 range - 'storage' and execution.
POP: "POP",
//DUP: "DUP",
//SWAP: "SWAP",
@@ -287,7 +297,7 @@ var opCodeToString = map[OpCode]string{
GAS: "GAS",
JUMPDEST: "JUMPDEST",
- // 0x60 range - push
+ // 0x60 range - push.
PUSH1: "PUSH1",
PUSH2: "PUSH2",
PUSH3: "PUSH3",
@@ -360,12 +370,13 @@ var opCodeToString = map[OpCode]string{
LOG3: "LOG3",
LOG4: "LOG4",
- // 0xf0 range
+ // 0xf0 range.
CREATE: "CREATE",
CALL: "CALL",
RETURN: "RETURN",
CALLCODE: "CALLCODE",
DELEGATECALL: "DELEGATECALL",
+ CREATE2: "CREATE2",
STATICCALL: "STATICCALL",
REVERT: "REVERT",
SELFDESTRUCT: "SELFDESTRUCT",
@@ -375,10 +386,10 @@ var opCodeToString = map[OpCode]string{
SWAP: "SWAP",
}
-func (o OpCode) String() string {
- str := opCodeToString[o]
+func (op OpCode) String() string {
+ str := opCodeToString[op]
if len(str) == 0 {
- return fmt.Sprintf("Missing opcode 0x%x", int(o))
+ return fmt.Sprintf("opcode 0x%x not defined", int(op))
}
return str
@@ -420,6 +431,7 @@ var stringToOp = map[string]OpCode{
"CALLDATALOAD": CALLDATALOAD,
"CALLDATASIZE": CALLDATASIZE,
"CALLDATACOPY": CALLDATACOPY,
+ "CHAINID": CHAINID,
"DELEGATECALL": DELEGATECALL,
"STATICCALL": STATICCALL,
"CODESIZE": CODESIZE,
@@ -429,12 +441,14 @@ var stringToOp = map[string]OpCode{
"EXTCODECOPY": EXTCODECOPY,
"RETURNDATASIZE": RETURNDATASIZE,
"RETURNDATACOPY": RETURNDATACOPY,
+ "EXTCODEHASH": EXTCODEHASH,
"BLOCKHASH": BLOCKHASH,
"COINBASE": COINBASE,
"TIMESTAMP": TIMESTAMP,
"NUMBER": NUMBER,
"DIFFICULTY": DIFFICULTY,
"GASLIMIT": GASLIMIT,
+ "SELFBALANCE": SELFBALANCE,
"POP": POP,
"MLOAD": MLOAD,
"MSTORE": MSTORE,
@@ -517,6 +531,7 @@ var stringToOp = map[string]OpCode{
"LOG3": LOG3,
"LOG4": LOG4,
"CREATE": CREATE,
+ "CREATE2": CREATE2,
"CALL": CALL,
"RETURN": RETURN,
"CALLCODE": CALLCODE,
@@ -524,6 +539,7 @@ var stringToOp = map[string]OpCode{
"SELFDESTRUCT": SELFDESTRUCT,
}
+// StringToOp finds the opcode whose name is stored in `str`.
func StringToOp(str string) OpCode {
return stringToOp[str]
}
diff --git a/core/vm/privacy/bulletproof.go b/core/vm/privacy/bulletproof.go
new file mode 100644
index 0000000000..9c2476590a
--- /dev/null
+++ b/core/vm/privacy/bulletproof.go
@@ -0,0 +1,1397 @@
+package privacy
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/sha256"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "math"
+ "math/big"
+ "strconv"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/log"
+
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/btcsuite/btcd/btcec"
+)
+
+type Bulletproof struct {
+ proofData []byte
+}
+
+var EC CryptoParams
+var VecLength = 512 // support maximum 8 spending value, each 64 bit (gwei is unit)
+var curve elliptic.Curve = crypto.S256()
+
+/*
+Implementation of BulletProofs
+*/
+type ECPoint struct {
+ X, Y *big.Int
+}
+
+func (p *ECPoint) toECPubKey() *ecdsa.PublicKey {
+ return &ecdsa.PublicKey{curve, p.X, p.Y}
+}
+
+func toECPoint(key *ecdsa.PublicKey) *ECPoint {
+ return &ECPoint{key.X, key.Y}
+}
+
+// Equal returns true if points p (self) and p2 (arg) are the same.
+func (p ECPoint) Equal(p2 ECPoint) bool {
+ if p.X.Cmp(p2.X) == 0 && p2.Y.Cmp(p2.Y) == 0 {
+ return true
+ }
+ return false
+}
+
+// Mult multiplies point p by scalar s and returns the resulting point
+func (p ECPoint) Mult(s *big.Int) ECPoint {
+ modS := new(big.Int).Mod(s, EC.N)
+ X, Y := EC.C.ScalarMult(p.X, p.Y, modS.Bytes())
+ return ECPoint{X, Y}
+}
+
+// Add adds points p and p2 and returns the resulting point
+func (p ECPoint) Add(p2 ECPoint) ECPoint {
+ X, Y := EC.C.Add(p.X, p.Y, p2.X, p2.Y)
+ return ECPoint{X, Y}
+}
+
+// Neg returns the additive inverse of point p
+func (p ECPoint) Neg() ECPoint {
+ negY := new(big.Int).Neg(p.Y)
+ modValue := negY.Mod(negY, EC.C.Params().P) // mod P is fine here because we're describing a curve point
+ return ECPoint{p.X, modValue}
+}
+
+type CryptoParams struct {
+ C elliptic.Curve // curve
+ KC *btcec.KoblitzCurve // curve
+ BPG []ECPoint // slice of gen 1 for BP
+ BPH []ECPoint // slice of gen 2 for BP
+ N *big.Int // scalar prime
+ U ECPoint // a point that is a fixed group element with an unknown discrete-log relative to g,h
+ V int // Vector length
+ G ECPoint // G value for commitments of a single value
+ H ECPoint // H value for commitments of a single value
+}
+
+func (c CryptoParams) Zero() ECPoint {
+ return ECPoint{big.NewInt(0), big.NewInt(0)}
+}
+
+func check(e error) {
+ if e != nil {
+ panic(e)
+ }
+}
+
+/*
+Vector Pedersen Commitment
+Given an array of values, we commit the array with different generators
+for each element and for each randomness.
+*/
+func VectorPCommit(value []*big.Int) (ECPoint, []*big.Int) {
+ R := make([]*big.Int, EC.V)
+
+ commitment := EC.Zero()
+
+ for i := 0; i < EC.V; i++ {
+ r, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+
+ R[i] = r
+
+ modValue := new(big.Int).Mod(value[i], EC.N)
+
+ // mG, rH
+ lhsX, lhsY := EC.C.ScalarMult(EC.BPG[i].X, EC.BPG[i].Y, modValue.Bytes())
+ rhsX, rhsY := EC.C.ScalarMult(EC.BPH[i].X, EC.BPH[i].Y, r.Bytes())
+
+ commitment = commitment.Add(ECPoint{lhsX, lhsY}).Add(ECPoint{rhsX, rhsY})
+ }
+
+ return commitment, R
+}
+
+/*
+Two Vector P Commit
+Given an array of values, we commit the array with different generators
+for each element and for each randomness.
+*/
+func TwoVectorPCommit(a []*big.Int, b []*big.Int) ECPoint {
+ if len(a) != len(b) {
+ log.Debug("TwoVectorPCommit: Arrays not of the same length", "len(a)", len(a), "len(b)", len(b))
+ }
+
+ commitment := EC.Zero()
+
+ for i := 0; i < EC.V; i++ {
+ commitment = commitment.Add(EC.BPG[i].Mult(a[i])).Add(EC.BPH[i].Mult(b[i]))
+ }
+
+ return commitment
+}
+
+/*
+Vector Pedersen Commitment with Gens
+Given an array of values, we commit the array with different generators
+for each element and for each randomness.
+We also pass in the Generators we want to use
+*/
+func TwoVectorPCommitWithGens(G, H []ECPoint, a, b []*big.Int) ECPoint {
+ if len(G) != len(H) || len(G) != len(a) || len(a) != len(b) {
+ log.Debug("TwoVectorPCommitWithGens: Arrays not of the same length", "len(G)", len(G), "len(H)", len(H), "len(a)", len(a), "len(b)", len(b))
+ }
+
+ commitment := EC.Zero()
+
+ for i := 0; i < len(G); i++ {
+ modA := new(big.Int).Mod(a[i], EC.N)
+ modB := new(big.Int).Mod(b[i], EC.N)
+
+ commitment = commitment.Add(G[i].Mult(modA)).Add(H[i].Mult(modB))
+ }
+
+ return commitment
+}
+
+// The length here always has to be a power of two
+func InnerProduct(a []*big.Int, b []*big.Int) *big.Int {
+ if len(a) != len(b) {
+ log.Debug("InnerProduct: Arrays not of the same length", "len(a)", len(a), "len(b", len(b))
+ }
+
+ c := big.NewInt(0)
+
+ for i := range a {
+ tmp1 := new(big.Int).Mul(a[i], b[i])
+ c = new(big.Int).Add(c, new(big.Int).Mod(tmp1, EC.N))
+ }
+
+ return new(big.Int).Mod(c, EC.N)
+}
+
+func VectorAdd(v []*big.Int, w []*big.Int) []*big.Int {
+ if len(v) != len(w) {
+ log.Debug("VectorAdd: Arrays not of the same length", "len(v)", len(v), "len(w)", len(w))
+ }
+ result := make([]*big.Int, len(v))
+
+ for i := range v {
+ result[i] = new(big.Int).Mod(new(big.Int).Add(v[i], w[i]), EC.N)
+ }
+
+ return result
+}
+
+func VectorHadamard(v, w []*big.Int) []*big.Int {
+ if len(v) != len(w) {
+ log.Debug("VectorHadamard: Arrays not of the same length", "len(v)", len(v), "len(w)", len(w))
+ }
+
+ result := make([]*big.Int, len(v))
+
+ for i := range v {
+ result[i] = new(big.Int).Mod(new(big.Int).Mul(v[i], w[i]), EC.N)
+ }
+
+ return result
+}
+
+func VectorAddScalar(v []*big.Int, s *big.Int) []*big.Int {
+ result := make([]*big.Int, len(v))
+
+ for i := range v {
+ result[i] = new(big.Int).Mod(new(big.Int).Add(v[i], s), EC.N)
+ }
+
+ return result
+}
+
+func ScalarVectorMul(v []*big.Int, s *big.Int) []*big.Int {
+ result := make([]*big.Int, len(v))
+
+ for i := range v {
+ result[i] = new(big.Int).Mod(new(big.Int).Mul(v[i], s), EC.N)
+ }
+
+ return result
+}
+
+func HashPointsToBytes(points []ECPoint) []byte {
+ input := []byte{}
+
+ for index := 0; index < len(points); index++ {
+ pointInByte := append(PadTo32Bytes(points[index].X.Bytes()), PadTo32Bytes(points[index].Y.Bytes())...)
+ input = append(input, pointInByte...)
+ }
+
+ return crypto.Keccak256(input)
+}
+
+/*
+InnerProd Proof
+This stores the argument values
+*/
+type InnerProdArg struct {
+ L []ECPoint
+ R []ECPoint
+ A *big.Int
+ B *big.Int
+
+ Challenges []*big.Int
+}
+
+func GenerateNewParams(G, H []ECPoint, x *big.Int, L, R, P ECPoint) ([]ECPoint, []ECPoint, ECPoint) {
+ nprime := len(G) / 2
+
+ Gprime := make([]ECPoint, nprime)
+ Hprime := make([]ECPoint, nprime)
+
+ xinv := new(big.Int).ModInverse(x, EC.N)
+
+ // Gprime = xinv * G[:nprime] + x*G[nprime:]
+ // Hprime = x * H[:nprime] + xinv*H[nprime:]
+
+ for i := range Gprime {
+ //fmt.Printf("i: %d && i+nprime: %d\n", i, i+nprime)
+ Gprime[i] = G[i].Mult(xinv).Add(G[i+nprime].Mult(x))
+ Hprime[i] = H[i].Mult(x).Add(H[i+nprime].Mult(xinv))
+ }
+
+ x2 := new(big.Int).Mod(new(big.Int).Mul(x, x), EC.N)
+ xinv2 := new(big.Int).ModInverse(x2, EC.N)
+
+ Pprime := L.Mult(x2).Add(P).Add(R.Mult(xinv2)) // x^2 * L + P + xinv^2 * R
+
+ return Gprime, Hprime, Pprime
+}
+
+/* Inner Product Argument
+Proves that =c
+This is a building block for BulletProofs
+*/
+func InnerProductProveSub(proof InnerProdArg, G, H []ECPoint, a []*big.Int, b []*big.Int, u ECPoint, P ECPoint) InnerProdArg {
+ if len(a) == 1 {
+ // Prover sends a & b
+ proof.A = a[0]
+ proof.B = b[0]
+ return proof
+ }
+
+ curIt := int(math.Log2(float64(len(a)))) - 1
+
+ nprime := len(a) / 2
+ cl := InnerProduct(a[:nprime], b[nprime:]) // either this line
+ cr := InnerProduct(a[nprime:], b[:nprime]) // or this line
+ L := TwoVectorPCommitWithGens(G[nprime:], H[:nprime], a[:nprime], b[nprime:]).Add(u.Mult(cl))
+ R := TwoVectorPCommitWithGens(G[:nprime], H[nprime:], a[nprime:], b[:nprime]).Add(u.Mult(cr))
+
+ proof.L[curIt] = L
+ proof.R[curIt] = R
+
+ // prover sends L & R and gets a challenge
+ // LvalInBytes := append(PadTo32Bytes(L.X.Bytes()), PadTo32Bytes(L.Y.Bytes())...)
+ // RvalInBytes := append(PadTo32Bytes(R.X.Bytes()), PadTo32Bytes(R.Y.Bytes())...)
+ // input := append(LvalInBytes, RvalInBytes...)
+ // s256 := crypto.Keccak256(input)
+ s256 := HashPointsToBytes([]ECPoint{L, R})
+
+ x := new(big.Int).SetBytes(s256[:])
+
+ proof.Challenges[curIt] = x
+
+ Gprime, Hprime, Pprime := GenerateNewParams(G, H, x, L, R, P)
+
+ xinv := new(big.Int).ModInverse(x, EC.N)
+
+ // or these two lines
+ aprime := VectorAdd(
+ ScalarVectorMul(a[:nprime], x),
+ ScalarVectorMul(a[nprime:], xinv))
+ bprime := VectorAdd(
+ ScalarVectorMul(b[:nprime], xinv),
+ ScalarVectorMul(b[nprime:], x))
+
+ return InnerProductProveSub(proof, Gprime, Hprime, aprime, bprime, u, Pprime)
+}
+
+//rpresult.IPP = InnerProductProve(left, right, that, P, EC.U, EC.BPG, HPrime)
+func InnerProductProve(a []*big.Int, b []*big.Int, c *big.Int, P, U ECPoint, G, H []ECPoint) InnerProdArg {
+ loglen := int(math.Log2(float64(len(a))))
+
+ challenges := make([]*big.Int, loglen+1)
+ Lvals := make([]ECPoint, loglen)
+ Rvals := make([]ECPoint, loglen)
+
+ runningProof := InnerProdArg{
+ Lvals,
+ Rvals,
+ big.NewInt(0),
+ big.NewInt(0),
+ challenges}
+
+ // randomly generate an x value from public data
+ // input := append(PadTo32Bytes(P.X.Bytes()), PadTo32Bytes(P.Y.Bytes())...)
+ // x := crypto.Keccak256(input)
+ x := HashPointsToBytes([]ECPoint{P})
+
+ runningProof.Challenges[loglen] = new(big.Int).SetBytes(x[:])
+
+ Pprime := P.Add(U.Mult(new(big.Int).Mul(new(big.Int).SetBytes(x[:]), c)))
+
+ ux := U.Mult(new(big.Int).SetBytes(x[:]))
+ //fmt.Printf("Prover Pprime value to run sub off of: %s\n", Pprime)
+
+ return InnerProductProveSub(runningProof, G, H, a, b, ux, Pprime)
+}
+
+/* Inner Product Verify
+Given a inner product proof, verifies the correctness of the proof
+Since we're using the Fiat-Shamir transform, we need to verify all x hash computations,
+all g' and h' computations
+P : the Pedersen commitment we are verifying is a commitment to the innner product
+ipp : the proof
+*/
+func InnerProductVerify(c *big.Int, P, U ECPoint, G, H []ECPoint, ipp InnerProdArg) bool {
+ //fmt.Println("Verifying Inner Product Argument")
+ //fmt.Printf("Commitment Value: %s \n", P)
+ // s1 := sha256.Sum256([]byte(P.X.String() + P.Y.String()))
+
+ // input := append(PadTo32Bytes(P.X.Bytes()), PadTo32Bytes(P.Y.Bytes())...)
+ // s1 := crypto.Keccak256(input)
+ s1 := HashPointsToBytes([]ECPoint{P})
+
+ chal1 := new(big.Int).SetBytes(s1[:])
+ ux := U.Mult(chal1)
+ curIt := len(ipp.Challenges) - 1
+
+ if ipp.Challenges[curIt].Cmp(chal1) != 0 {
+ log.Info("Initial Challenge Failed")
+ return false
+ }
+
+ curIt -= 1
+
+ Gprime := G
+ Hprime := H
+ Pprime := P.Add(ux.Mult(c)) // line 6 from protocol 1
+ //fmt.Printf("New Commitment value with u^cx: %s \n", Pprime)
+
+ for curIt >= 0 {
+ Lval := ipp.L[curIt]
+ Rval := ipp.R[curIt]
+
+ // prover sends L & R and gets a challenge
+ // s256 := sha256.Sum256([]byte(
+ // Lval.X.String() + Lval.Y.String() +
+ // Rval.X.String() + Rval.Y.String()))
+ // LvalInBytes := append(PadTo32Bytes(Lval.X.Bytes()), PadTo32Bytes(Lval.Y.Bytes())...)
+ // RvalInBytes := append(PadTo32Bytes(Rval.X.Bytes()), PadTo32Bytes(Rval.Y.Bytes())...)
+ // input := append(LvalInBytes, RvalInBytes...)
+ // s256 := crypto.Keccak256(input)
+ s256 := HashPointsToBytes([]ECPoint{Lval, Rval})
+
+ chal2 := new(big.Int).SetBytes(s256[:])
+
+ if ipp.Challenges[curIt].Cmp(chal2) != 0 {
+ log.Info("Challenge verification failed", "index", strconv.Itoa(curIt))
+ return false
+ }
+
+ Gprime, Hprime, Pprime = GenerateNewParams(Gprime, Hprime, chal2, Lval, Rval, Pprime)
+ curIt -= 1
+ }
+ ccalc := new(big.Int).Mod(new(big.Int).Mul(ipp.A, ipp.B), EC.N)
+
+ Pcalc1 := Gprime[0].Mult(ipp.A)
+ Pcalc2 := Hprime[0].Mult(ipp.B)
+ Pcalc3 := ux.Mult(ccalc)
+ Pcalc := Pcalc1.Add(Pcalc2).Add(Pcalc3)
+
+ if !Pprime.Equal(Pcalc) {
+ return false
+ }
+
+ return true
+}
+
+/* Inner Product Verify Fast
+Given a inner product proof, verifies the correctness of the proof. Does the same as above except
+we replace n separate exponentiations with a single multi-exponentiation.
+*/
+
+func InnerProductVerifyFast(c *big.Int, P, U ECPoint, G, H []ECPoint, ipp InnerProdArg) bool {
+ // input := append(PadTo32Bytes(P.X.Bytes()), PadTo32Bytes(P.Y.Bytes())...)
+ // s1 := crypto.Keccak256(input)
+ s1 := HashPointsToBytes([]ECPoint{P})
+
+ chal1 := new(big.Int).SetBytes(s1[:])
+ ux := U.Mult(chal1)
+ curIt := len(ipp.Challenges) - 1
+
+ // check all challenges
+ if ipp.Challenges[curIt].Cmp(chal1) != 0 {
+ log.Debug("Initial Challenge Failed")
+ return false
+ }
+
+ for j := curIt - 1; j >= 0; j-- {
+ Lval := ipp.L[j]
+ Rval := ipp.R[j]
+
+ // prover sends L & R and gets a challenge
+ // LvalInBytes := append(PadTo32Bytes(Lval.X.Bytes()), PadTo32Bytes(Lval.Y.Bytes())...)
+ // RvalInBytes := append(PadTo32Bytes(Rval.X.Bytes()), PadTo32Bytes(Rval.Y.Bytes())...)
+ // input := append(LvalInBytes, RvalInBytes...)
+ // s256 := crypto.Keccak256(input)
+ s256 := HashPointsToBytes([]ECPoint{Lval, Rval})
+
+ chal2 := new(big.Int).SetBytes(s256[:])
+
+ if ipp.Challenges[j].Cmp(chal2) != 0 {
+ log.Debug("Challenge verification failed", "index", strconv.Itoa(j))
+ return false
+ }
+ }
+ // begin computing
+
+ curIt -= 1
+ Pprime := P.Add(ux.Mult(c)) // line 6 from protocol 1
+
+ tmp1 := EC.Zero()
+ for j := curIt; j >= 0; j-- {
+ x2 := new(big.Int).Exp(ipp.Challenges[j], big.NewInt(2), EC.N)
+ x2i := new(big.Int).ModInverse(x2, EC.N)
+ //fmt.Println(tmp1)
+ tmp1 = ipp.L[j].Mult(x2).Add(ipp.R[j].Mult(x2i)).Add(tmp1)
+ //fmt.Println(tmp1)
+ }
+ rhs := Pprime.Add(tmp1)
+ //rhs=P+c*ux + L*xw+R*x2i 公式29
+
+ sScalars := make([]*big.Int, EC.V)
+ invsScalars := make([]*big.Int, EC.V)
+
+ for i := 0; i < EC.V; i++ {
+ si := big.NewInt(1)
+ for j := curIt; j >= 0; j-- {
+ // original challenge if the jth bit of i is 1, inverse challenge otherwise
+ chal := ipp.Challenges[j]
+ if big.NewInt(int64(i)).Bit(j) == 0 {
+ chal = new(big.Int).ModInverse(chal, EC.N)
+ }
+ // fmt.Printf("Challenge raised to value: %d\n", chal)
+ si = new(big.Int).Mod(new(big.Int).Mul(si, chal), EC.N)
+ }
+ //fmt.Printf("Si value: %d\n", si)
+ sScalars[i] = si
+ invsScalars[i] = new(big.Int).ModInverse(si, EC.N)
+ }
+
+ ccalc := new(big.Int).Mod(new(big.Int).Mul(ipp.A, ipp.B), EC.N)
+ lhs := TwoVectorPCommitWithGens(G, H, ScalarVectorMul(sScalars, ipp.A), ScalarVectorMul(invsScalars, ipp.B)).Add(ux.Mult(ccalc))
+
+ if !rhs.Equal(lhs) {
+ log.Info("IPVerify - Final Commitment checking failed")
+ return false
+ }
+
+ return true
+}
+
+// from here: https://play.golang.org/p/zciRZvD0Gr with a fix
+func PadLeft(str, pad string, l int) string {
+ strCopy := str
+ for len(strCopy) < l {
+ strCopy = pad + strCopy
+ }
+
+ return strCopy
+}
+
+func STRNot(str string) string {
+ result := ""
+
+ for _, i := range str {
+ if i == '0' {
+ result += "1"
+ } else {
+ result += "0"
+ }
+ }
+ return result
+}
+
+func StrToBigIntArray(str string) []*big.Int {
+ result := make([]*big.Int, len(str))
+
+ for i := range str {
+ t, success := new(big.Int).SetString(string(str[i]), 10)
+ if success {
+ result[i] = t
+ }
+ }
+
+ return result
+}
+
+func reverse(l []*big.Int) []*big.Int {
+ result := make([]*big.Int, len(l))
+
+ for i := range l {
+ result[i] = l[len(l)-i-1]
+ }
+
+ return result
+}
+
+func PowerVector(l int, base *big.Int) []*big.Int {
+ result := make([]*big.Int, l)
+
+ for i := 0; i < l; i++ {
+ result[i] = new(big.Int).Exp(base, big.NewInt(int64(i)), EC.N)
+ }
+
+ return result
+}
+
+func RandVector(l int) []*big.Int {
+ result := make([]*big.Int, l)
+
+ for i := 0; i < l; i++ {
+ x, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+ result[i] = x
+ }
+
+ return result
+}
+
+func VectorSum(y []*big.Int) *big.Int {
+ result := big.NewInt(0)
+
+ for _, j := range y {
+ result = new(big.Int).Mod(new(big.Int).Add(result, j), EC.N)
+ }
+
+ return result
+}
+
+type RangeProof struct {
+ Comm ECPoint
+ A ECPoint
+ S ECPoint
+ T1 ECPoint
+ T2 ECPoint
+ Tau *big.Int
+ Th *big.Int
+ Mu *big.Int
+ IPP InnerProdArg
+
+ // challenges
+ Cy *big.Int
+ Cz *big.Int
+ Cx *big.Int
+}
+
+/*
+Delta is a helper function that is used in the range proof
+\delta(y, z) = (z-z^2)<1^n, y^n> - z^3<1^n, 2^n>
+*/
+
+func Delta(y []*big.Int, z *big.Int) *big.Int {
+ result := big.NewInt(0)
+
+ // (z-z^2)<1^n, y^n>
+ z2 := new(big.Int).Mod(new(big.Int).Mul(z, z), EC.N)
+ t1 := new(big.Int).Mod(new(big.Int).Sub(z, z2), EC.N)
+ t2 := new(big.Int).Mod(new(big.Int).Mul(t1, VectorSum(y)), EC.N)
+
+ // z^3<1^n, 2^n>
+ z3 := new(big.Int).Mod(new(big.Int).Mul(z2, z), EC.N)
+ po2sum := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(EC.V)), EC.N), big.NewInt(1))
+ t3 := new(big.Int).Mod(new(big.Int).Mul(z3, po2sum), EC.N)
+
+ result = new(big.Int).Mod(new(big.Int).Sub(t2, t3), EC.N)
+
+ return result
+}
+
+// Calculates (aL - z*1^n) + sL*x
+func CalculateL(aL, sL []*big.Int, z, x *big.Int) []*big.Int {
+ result := make([]*big.Int, len(aL))
+
+ tmp1 := VectorAddScalar(aL, new(big.Int).Neg(z))
+ tmp2 := ScalarVectorMul(sL, x)
+
+ result = VectorAdd(tmp1, tmp2)
+
+ return result
+}
+
+func CalculateR(aR, sR, y, po2 []*big.Int, z, x *big.Int) []*big.Int {
+ if len(aR) != len(sR) || len(aR) != len(y) || len(y) != len(po2) {
+ log.Info("CalculateR: Arrays not of the same length")
+ }
+
+ result := make([]*big.Int, len(aR))
+
+ z2 := new(big.Int).Exp(z, big.NewInt(2), EC.N)
+ tmp11 := VectorAddScalar(aR, z)
+ tmp12 := ScalarVectorMul(sR, x)
+ tmp1 := VectorHadamard(y, VectorAdd(tmp11, tmp12))
+ tmp2 := ScalarVectorMul(po2, z2)
+
+ result = VectorAdd(tmp1, tmp2)
+
+ return result
+}
+
+// Calculates (aL - z*1^n) + sL*x
+func CalculateLMRP(aL, sL []*big.Int, z, x *big.Int) []*big.Int {
+ result := make([]*big.Int, len(aL))
+
+ tmp1 := VectorAddScalar(aL, new(big.Int).Neg(z))
+ tmp2 := ScalarVectorMul(sL, x)
+
+ result = VectorAdd(tmp1, tmp2)
+
+ return result
+}
+
+func CalculateRMRP(aR, sR, y, zTimesTwo []*big.Int, z, x *big.Int) []*big.Int {
+ if len(aR) != len(sR) || len(aR) != len(y) || len(y) != len(zTimesTwo) {
+ log.Info("CalculateRMRP: Arrays not of the same length")
+ }
+
+ result := make([]*big.Int, len(aR))
+
+ tmp11 := VectorAddScalar(aR, z)
+ tmp12 := ScalarVectorMul(sR, x)
+ tmp1 := VectorHadamard(y, VectorAdd(tmp11, tmp12))
+
+ result = VectorAdd(tmp1, zTimesTwo)
+
+ return result
+}
+
+/*
+DeltaMRP is a helper function that is used in the multi range proof
+\delta(y, z) = (z-z^2)<1^n, y^n> - \sum_j z^3+j<1^n, 2^n>
+*/
+
+func DeltaMRP(y []*big.Int, z *big.Int, m int) *big.Int {
+ result := big.NewInt(0)
+
+ // (z-z^2)<1^n, y^n>
+ z2 := new(big.Int).Mod(new(big.Int).Mul(z, z), EC.N)
+ t1 := new(big.Int).Mod(new(big.Int).Sub(z, z2), EC.N)
+ t2 := new(big.Int).Mod(new(big.Int).Mul(t1, VectorSum(y)), EC.N)
+
+ // \sum_j z^3+j<1^n, 2^n>
+ // <1^n, 2^n> = 2^n - 1
+ po2sum := new(big.Int).Sub(
+ new(big.Int).Exp(
+ big.NewInt(2), big.NewInt(int64(EC.V/m)), EC.N), big.NewInt(1))
+ t3 := big.NewInt(0)
+
+ for j := 0; j < m; j++ {
+ zp := new(big.Int).Exp(z, big.NewInt(3+int64(j)), EC.N)
+ tmp1 := new(big.Int).Mod(new(big.Int).Mul(zp, po2sum), EC.N)
+ t3 = new(big.Int).Mod(new(big.Int).Add(t3, tmp1), EC.N)
+ }
+
+ result = new(big.Int).Mod(new(big.Int).Sub(t2, t3), EC.N)
+
+ return result
+}
+
+type MultiRangeProof struct {
+ Comms []ECPoint
+ A ECPoint
+ S ECPoint
+ T1 ECPoint
+ T2 ECPoint
+ Tau *big.Int
+ Th *big.Int
+ Mu *big.Int
+ IPP InnerProdArg
+
+ // challenges
+ Cy *big.Int
+ Cz *big.Int
+ Cx *big.Int
+}
+
+func serializePointArray(pa []ECPoint, serializeSize bool) []byte {
+ ret := []byte{}
+
+ if serializeSize {
+ size := make([]byte, 4)
+ binary.BigEndian.PutUint32(size, uint32(len(pa)))
+ ret = append(ret, size[:]...)
+ }
+
+ for i := 0; i < len(pa); i++ {
+ sp := SerializeCompressed(pa[i].toECPubKey())
+ ret = append(ret, sp[:]...)
+ }
+ return ret
+}
+
+func deserializePointArray(input []byte, numPoint uint32) ([]ECPoint, error) {
+ if len(input) <= 4 {
+ return []ECPoint{}, errors.New("input data invalid")
+ }
+ numPointSize := uint32(0)
+ if numPoint == 0 {
+ numPointSize = 4
+ numPoint = binary.BigEndian.Uint32(input[0:4])
+ }
+ if uint32(len(input)) < (numPointSize + 33*numPoint) {
+ return []ECPoint{}, errors.New("input data too short")
+ }
+ ret := make([]ECPoint, numPoint)
+ offset := numPointSize
+ for i := 0; i < int(numPoint); i++ {
+ compressed := DeserializeCompressed(curve, input[offset:offset+33])
+ if compressed == nil {
+ return ret, errors.New("invalid input data")
+ }
+ ret[i] = *toECPoint(compressed)
+ offset += 33
+ }
+ return ret, nil
+}
+
+func (ipp *InnerProdArg) Serialize() []byte {
+ proof := []byte{}
+
+ spa := serializePointArray(ipp.L, false)
+ proof = append(proof, spa[:]...)
+
+ spa = serializePointArray(ipp.R, false)
+ proof = append(proof, spa[:]...)
+
+ if ipp.A.Cmp(big.NewInt(0)) < 0 {
+ ipp.A.Mod(ipp.A, EC.N)
+ }
+ sp := PadTo32Bytes(ipp.A.Bytes())
+ proof = append(proof, sp[:]...)
+
+ sp = PadTo32Bytes(ipp.B.Bytes())
+ proof = append(proof, sp[:]...)
+
+ for i := 0; i < len(ipp.Challenges); i++ {
+ sp = PadTo32Bytes(ipp.Challenges[i].Bytes())
+ proof = append(proof, sp[:]...)
+ }
+
+ return proof
+}
+
+func (ipp *InnerProdArg) Deserialize(proof []byte, numChallenges int) error {
+ if len(proof) <= 12 {
+ return errors.New("proof data too short")
+ }
+ offset := 0
+ L, err := deserializePointArray(proof[:], uint32(numChallenges)-1)
+ if err != nil {
+ return err
+ }
+ ipp.L = append(ipp.L, L[:]...)
+ offset += len(L) * 33
+
+ R, err := deserializePointArray(proof[offset:], uint32(numChallenges)-1)
+ if err != nil {
+ return err
+ }
+
+ ipp.R = append(ipp.R, R[:]...)
+ offset += len(R) * 33
+
+ if len(proof) <= offset+64+4 {
+ return errors.New("proof data too short")
+ }
+
+ ipp.A = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+ ipp.B = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ if len(proof) <= (offset + 32*numChallenges) {
+ return errors.New("input data too short")
+ }
+ for i := 0; i < int(numChallenges); i++ {
+ ipp.Challenges = append(ipp.Challenges, new(big.Int).SetBytes(proof[offset:offset+32]))
+ offset += 32
+ }
+ return nil
+}
+
+func (mrp *MultiRangeProof) Serialize() []byte {
+ proof := []byte{}
+
+ serializedPA := serializePointArray(mrp.Comms, true)
+ proof = append(proof, serializedPA[:]...)
+
+ sp := SerializeCompressed(mrp.A.toECPubKey())
+ proof = append(proof, sp[:]...)
+
+ sp = SerializeCompressed(mrp.S.toECPubKey())
+ proof = append(proof, sp[:]...)
+
+ sp = SerializeCompressed(mrp.T1.toECPubKey())
+ proof = append(proof, sp[:]...)
+
+ sp = SerializeCompressed(mrp.T2.toECPubKey())
+ proof = append(proof, sp[:]...)
+
+ //Tau, Th, Mu
+ sp = PadTo32Bytes(mrp.Tau.Bytes())
+ proof = append(proof, sp[:]...)
+
+ if mrp.Th.Cmp(big.NewInt(0)) < 0 {
+ mrp.Th.Mod(mrp.Th, EC.N)
+ }
+ sp = PadTo32Bytes(mrp.Th.Bytes())
+ proof = append(proof, sp[:]...)
+
+ sp = PadTo32Bytes(mrp.Mu.Bytes())
+ proof = append(proof, sp[:]...)
+
+ //challenges
+ sp = mrp.IPP.Serialize()
+ proof = append(proof, sp[:]...)
+
+ //challenges
+ sp = PadTo32Bytes(mrp.Cy.Bytes())
+ proof = append(proof, sp[:]...)
+
+ sp = PadTo32Bytes(mrp.Cz.Bytes())
+ proof = append(proof, sp[:]...)
+
+ sp = PadTo32Bytes(mrp.Cx.Bytes())
+ proof = append(proof, sp[:]...)
+
+ return proof
+}
+
+func (mrp *MultiRangeProof) Deserialize(proof []byte) error {
+ Cs, err := deserializePointArray(proof[:], 0)
+ if err != nil {
+ return err
+ }
+ mrp.Comms = append(mrp.Comms, Cs[:]...)
+
+ offset := 4 + len(Cs)*33
+
+ if len(proof) <= offset+4+4*33+6*32 {
+ return errors.New("invalid input data")
+ }
+ compressed := DeserializeCompressed(curve, proof[offset:offset+33])
+ if compressed == nil {
+ return errors.New("failed to decode A")
+ }
+ offset += 33
+ mrp.A = *toECPoint(compressed)
+
+ compressed = DeserializeCompressed(curve, proof[offset:offset+33])
+ if compressed == nil {
+ return errors.New("failed to decode S")
+ }
+ offset += 33
+ mrp.S = *toECPoint(compressed)
+
+ compressed = DeserializeCompressed(curve, proof[offset:offset+33])
+ if compressed == nil {
+ return errors.New("failed to decode T2")
+ }
+ offset += 33
+ mrp.T1 = *toECPoint(compressed)
+
+ compressed = DeserializeCompressed(curve, proof[offset:offset+33])
+ if compressed == nil {
+ return errors.New("failed to decode T2")
+ }
+ offset += 33
+ mrp.T2 = *toECPoint(compressed)
+
+ mrp.Tau = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ mrp.Th = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ mrp.Mu = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ numChallenges := int(math.Log2(float64(len(mrp.Comms)*bitsPerValue))) + 1
+ mrp.IPP.Deserialize(proof[offset:], numChallenges)
+ offset += len(mrp.IPP.L)*33 + len(mrp.IPP.R)*33 + len(mrp.IPP.Challenges)*32 + 2*32
+
+ mrp.Cy = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ mrp.Cz = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ mrp.Cx = new(big.Int).SetBytes(proof[offset : offset+32])
+ offset += 32
+
+ return nil
+}
+
+func pedersenCommitment(gamma *big.Int, value *big.Int) ECPoint {
+ return EC.G.Mult(value).Add(EC.H.Mult(gamma))
+}
+
+var MAX_64_BITS = new(big.Int).SetUint64(0xFFFFFFFFFFFFFFFF)
+
+/*
+MultiRangeProof Prove
+Takes in a list of values and provides an aggregate
+range proof for all the values.
+changes:
+ all values are concatenated
+ r(x) is computed differently
+ tau_x calculation is different
+ delta calculation is different
+{(g, h \in G, \textbf{V} \in G^m ; \textbf{v, \gamma} \in Z_p^m) :
+ V_j = h^{\gamma_j}g^{v_j} \wedge v_j \in [0, 2^n - 1] \forall j \in [1, m]}
+*/
+var bitsPerValue = 64
+
+func MRPProve(values []*big.Int) (MultiRangeProof, error) {
+ var acceptedInputNumber bool
+
+ MRPResult := MultiRangeProof{}
+
+ m := len(values)
+
+ if m == 1 || m == 2 || m == 4 || m == 8 {
+ acceptedInputNumber = true
+ }
+
+ if !acceptedInputNumber {
+ return MultiRangeProof{}, errors.New("Value number is not supported - just 1, 2, 4, 8")
+ }
+
+ EC = genECPrimeGroupKey(m * bitsPerValue)
+
+ // we concatenate the binary representation of the values
+
+ PowerOfTwos := PowerVector(bitsPerValue, big.NewInt(2))
+
+ Comms := make([]ECPoint, m)
+ gammas := make([]*big.Int, m)
+ aLConcat := make([]*big.Int, EC.V)
+ aRConcat := make([]*big.Int, EC.V)
+
+ for j := range values {
+ v := values[j]
+ if v.Cmp(big.NewInt(0)) == -1 {
+ return MultiRangeProof{}, errors.New("Value is below range! Not proving")
+ }
+
+ if v.Cmp(MAX_64_BITS) == 1 {
+ return MultiRangeProof{}, errors.New("Value is above range! Not proving")
+ }
+
+ if v.Cmp(new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(bitsPerValue)), EC.N)) == 1 {
+ return MultiRangeProof{}, errors.New("Value is above range! Not proving")
+ }
+
+ gamma, err := rand.Int(rand.Reader, EC.N)
+
+ check(err)
+ Comms[j] = pedersenCommitment(gamma, v)
+ gammas[j] = gamma
+
+ // break up v into its bitwise representation
+ aL := reverse(StrToBigIntArray(PadLeft(fmt.Sprintf("%b", v), "0", bitsPerValue)))
+ aR := VectorAddScalar(aL, big.NewInt(-1))
+
+ for i := range aR {
+ aLConcat[bitsPerValue*j+i] = aL[i]
+ aRConcat[bitsPerValue*j+i] = aR[i]
+ }
+ }
+
+ //compare aL, aR
+ MRPResult.Comms = Comms
+
+ alpha, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+
+ A := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, aLConcat, aRConcat).Add(EC.H.Mult(alpha))
+ MRPResult.A = A
+
+ // fmt.Println("Ec.V %+v", EC.V)
+ sL := RandVector(EC.V)
+ sR := RandVector(EC.V)
+
+ rho, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+
+ S := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, sL, sR).Add(EC.H.Mult(rho))
+ MRPResult.S = S
+
+ // input := append(PadTo32Bytes(A.X.Bytes()), PadTo32Bytes(A.Y.Bytes())...)
+ // chal1s256 := crypto.Keccak256(input)
+ chal1s256 := HashPointsToBytes(append(Comms, A))
+
+ // chal1s256 := sha256.Sum256([]byte(A.X.String() + A.Y.String()))
+ cy := new(big.Int).SetBytes(chal1s256[:])
+ MRPResult.Cy = cy
+
+ // input = append(PadTo32Bytes(S.X.Bytes()), PadTo32Bytes(S.Y.Bytes())...)
+ // chal2s256 := crypto.Keccak256(input)
+ chal2s256 := HashPointsToBytes(append(Comms, A, S))
+
+ // chal2s256 := sha256.Sum256([]byte(S.X.String() + S.Y.String()))
+ cz := new(big.Int).SetBytes(chal2s256[:])
+ MRPResult.Cz = cz
+
+ zPowersTimesTwoVec := make([]*big.Int, EC.V)
+ for j := 0; j < m; j++ {
+ zp := new(big.Int).Exp(cz, big.NewInt(2+int64(j)), EC.N)
+ for i := 0; i < bitsPerValue; i++ {
+ zPowersTimesTwoVec[j*bitsPerValue+i] = new(big.Int).Mod(new(big.Int).Mul(PowerOfTwos[i], zp), EC.N)
+ }
+ }
+
+ PowerOfCY := PowerVector(EC.V, cy)
+ // fmt.Println(PowerOfCY)
+ l0 := VectorAddScalar(aLConcat, new(big.Int).Neg(cz))
+ l1 := sL
+ r0 := VectorAdd(
+ VectorHadamard(
+ PowerOfCY,
+ VectorAddScalar(aRConcat, cz)),
+ zPowersTimesTwoVec)
+ r1 := VectorHadamard(sR, PowerOfCY)
+
+ //calculate t0
+ vz2 := big.NewInt(0)
+ z2 := new(big.Int).Mod(new(big.Int).Mul(cz, cz), EC.N)
+ PowerOfCZ := PowerVector(m, cz)
+ for j := 0; j < m; j++ {
+ vz2 = new(big.Int).Add(vz2,
+ new(big.Int).Mul(
+ PowerOfCZ[j],
+ new(big.Int).Mul(values[j], z2)))
+ vz2 = new(big.Int).Mod(vz2, EC.N)
+ }
+
+ t0 := new(big.Int).Mod(new(big.Int).Add(vz2, DeltaMRP(PowerOfCY, cz, m)), EC.N)
+
+ t1 := new(big.Int).Mod(new(big.Int).Add(InnerProduct(l1, r0), InnerProduct(l0, r1)), EC.N)
+ t2 := InnerProduct(l1, r1)
+
+ // given the t_i values, we can generate commitments to them
+ tau1, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+ tau2, err := rand.Int(rand.Reader, EC.N)
+ check(err)
+
+ T1 := pedersenCommitment(tau1, t1) // EC.G.Mult(t1).Add(EC.H.Mult(tau1)) //commitment to t1
+ T2 := pedersenCommitment(tau2, t2) //EC.G.Mult(t2).Add(EC.H.Mult(tau2)) //commitment to t2
+
+ MRPResult.T1 = T1
+ MRPResult.T2 = T2
+
+ // t1Byte := append(PadTo32Bytes(T1.X.Bytes()), PadTo32Bytes(T1.Y.Bytes())...)
+ // t2Byte := append(PadTo32Bytes(T2.X.Bytes()), PadTo32Bytes(T2.Y.Bytes())...)
+ // input = append(t1Byte, t2Byte...)
+ // chal3s256 := crypto.Keccak256(input)
+ chal3s256 := HashPointsToBytes(append(Comms, A, S, T1, T2))
+
+ // chal3s256 := sha256.Sum256([]byte(T1.X.String() + T1.Y.String() + T2.X.String() + T2.Y.String()))
+ cx := new(big.Int).SetBytes(chal3s256[:])
+
+ MRPResult.Cx = cx
+
+ left := CalculateLMRP(aLConcat, sL, cz, cx)
+ right := CalculateRMRP(aRConcat, sR, PowerOfCY, zPowersTimesTwoVec, cz, cx)
+
+ thatPrime := new(big.Int).Mod( // t0 + t1*x + t2*x^2
+ new(big.Int).Add(t0, new(big.Int).Add(new(big.Int).Mul(t1, cx), new(big.Int).Mul(new(big.Int).Mul(cx, cx), t2))), EC.N)
+
+ that := InnerProduct(left, right) // NOTE: BP Java implementation calculates this from the t_i
+
+ // thatPrime and that should be equal
+ if thatPrime.Cmp(that) != 0 {
+ fmt.Println("Proving -- Uh oh! Two diff ways to compute same value not working")
+ fmt.Printf("\tthatPrime = %s\n", thatPrime.String())
+ fmt.Printf("\tthat = %s \n", that.String())
+ }
+
+ MRPResult.Th = that
+
+ vecRandomnessTotal := big.NewInt(0)
+ for j := 0; j < m; j++ {
+ zp := new(big.Int).Exp(cz, big.NewInt(2+int64(j)), EC.N)
+ tmp1 := new(big.Int).Mul(gammas[j], zp)
+ vecRandomnessTotal = new(big.Int).Mod(new(big.Int).Add(vecRandomnessTotal, tmp1), EC.N)
+ }
+ //fmt.Println(vecRandomnessTotal)
+ taux1 := new(big.Int).Mod(new(big.Int).Mul(tau2, new(big.Int).Mul(cx, cx)), EC.N)
+ taux2 := new(big.Int).Mod(new(big.Int).Mul(tau1, cx), EC.N)
+ taux := new(big.Int).Mod(new(big.Int).Add(taux1, new(big.Int).Add(taux2, vecRandomnessTotal)), EC.N)
+
+ MRPResult.Tau = taux
+
+ mu := new(big.Int).Mod(new(big.Int).Add(alpha, new(big.Int).Mul(rho, cx)), EC.N)
+ MRPResult.Mu = mu
+
+ HPrime := make([]ECPoint, len(EC.BPH))
+
+ for i := range HPrime {
+ HPrime[i] = EC.BPH[i].Mult(new(big.Int).ModInverse(PowerOfCY[i], EC.N))
+ }
+
+ P := TwoVectorPCommitWithGens(EC.BPG, HPrime, left, right)
+ //fmt.Println(P)
+
+ MRPResult.IPP = InnerProductProve(left, right, that, P, EC.U, EC.BPG, HPrime)
+
+ return MRPResult, nil
+}
+
+/*
+MultiRangeProof Verify
+Takes in a MultiRangeProof and verifies its correctness
+*/
+func MRPVerify(mrp *MultiRangeProof) bool {
+ m := len(mrp.Comms)
+ EC = genECPrimeGroupKey(m * bitsPerValue)
+
+ //changes:
+ // check 1 changes since it includes all commitments
+ // check 2 commitment generation is also different
+
+ // verify the challenges
+ // input := append(PadTo32Bytes(mrp.A.X.Bytes()), PadTo32Bytes(mrp.A.Y.Bytes())...)
+ // chal1s256 := crypto.Keccak256(input)
+ chal1s256 := HashPointsToBytes(append(mrp.Comms, mrp.A))
+
+ cy := new(big.Int).SetBytes(chal1s256[:])
+
+ if cy.Cmp(mrp.Cy) != 0 {
+ log.Debug("MRPVerify challenge failed!", "Cy", common.Bytes2Hex(mrp.Cy.Bytes()))
+ return false
+ }
+
+ // input = append(PadTo32Bytes(mrp.S.X.Bytes()), PadTo32Bytes(mrp.S.Y.Bytes())...)
+ // chal2s256 := crypto.Keccak256(input)
+ chal2s256 := HashPointsToBytes(append(mrp.Comms, mrp.A, mrp.S))
+
+ // chal2s256 := sha256.Sum256([]byte(mrp.S.X.String() + mrp.S.Y.String()))
+ cz := new(big.Int).SetBytes(chal2s256[:])
+ if cz.Cmp(mrp.Cz) != 0 {
+ log.Debug("MRPVerify challenge failed!", "Cz", common.Bytes2Hex(mrp.Cz.Bytes()))
+ return false
+ }
+
+ // t1Byte := append(PadTo32Bytes(mrp.T1.X.Bytes()), PadTo32Bytes(mrp.T1.Y.Bytes())...)
+ // t2Byte := append(PadTo32Bytes(mrp.T2.X.Bytes()), PadTo32Bytes(mrp.T2.Y.Bytes())...)
+ // input = append(t1Byte, t2Byte...)
+ // chal3s256 := crypto.Keccak256(input)
+ chal3s256 := HashPointsToBytes(append(mrp.Comms, mrp.A, mrp.S, mrp.T1, mrp.T2))
+
+ // chal3s256 := sha256.Sum256([]byte(T1.X.String() + T1.Y.String() + T2.X.String() + T2.Y.String()))
+ // cx := new(big.Int).SetBytes(chal3s256[:])
+ //chal3s256 := sha256.Sum256([]byte(mrp.T1.X.String() + mrp.T1.Y.String() + mrp.T2.X.String() + mrp.T2.Y.String()))
+
+ cx := new(big.Int).SetBytes(chal3s256[:])
+
+ if cx.Cmp(mrp.Cx) != 0 {
+ log.Debug("MRPVerify challenge failed!", "Cx", common.Bytes2Hex(mrp.Cx.Bytes()))
+ return false
+ }
+
+ // given challenges are correct, very range proof
+ PowersOfY := PowerVector(EC.V, cy)
+
+ // t_hat * G + tau * H
+ lhs := pedersenCommitment(mrp.Tau, mrp.Th) //EC.G.Mult(mrp.Th).Add(EC.H.Mult(mrp.Tau))
+
+ // z^2 * \bold{z}^m \bold{V} + delta(y,z) * G + x * T1 + x^2 * T2
+ CommPowers := EC.Zero()
+ PowersOfZ := PowerVector(m, cz)
+ z2 := new(big.Int).Mod(new(big.Int).Mul(cz, cz), EC.N)
+
+ for j := 0; j < m; j++ {
+ CommPowers = CommPowers.Add(mrp.Comms[j].Mult(new(big.Int).Mul(z2, PowersOfZ[j])))
+ }
+
+ // TODO i need to change how to calculate the commitment here also ?
+ // need to compare and double check with privacy-client lib
+ rhs := EC.G.Mult(DeltaMRP(PowersOfY, cz, m)).Add(
+ mrp.T1.Mult(cx)).Add(
+ mrp.T2.Mult(new(big.Int).Mul(cx, cx))).Add(CommPowers)
+
+ if !lhs.Equal(rhs) {
+ log.Debug("Rangeproof failed")
+ return false
+ }
+
+ tmp1 := EC.Zero()
+ zneg := new(big.Int).Mod(new(big.Int).Neg(cz), EC.N)
+ for i := range EC.BPG {
+ tmp1 = tmp1.Add(EC.BPG[i].Mult(zneg))
+ }
+
+ PowerOfTwos := PowerVector(bitsPerValue, big.NewInt(2))
+ tmp2 := EC.Zero()
+ // generate h'
+ HPrime := make([]ECPoint, len(EC.BPH))
+
+ for i := range HPrime {
+ mi := new(big.Int).ModInverse(PowersOfY[i], EC.N)
+ HPrime[i] = EC.BPH[i].Mult(mi)
+ }
+
+ for j := 0; j < m; j++ {
+ for i := 0; i < bitsPerValue; i++ {
+ val1 := new(big.Int).Mul(cz, PowersOfY[j*bitsPerValue+i])
+ zp := new(big.Int).Exp(cz, big.NewInt(2+int64(j)), EC.N)
+ val2 := new(big.Int).Mod(new(big.Int).Mul(zp, PowerOfTwos[i]), EC.N)
+ tmp2 = tmp2.Add(HPrime[j*bitsPerValue+i].Mult(new(big.Int).Add(val1, val2)))
+ }
+ }
+
+ // without subtracting this value should equal muCH + l[i]G[i] + r[i]H'[i]
+ // we want to make sure that the innerproduct checks out, so we subtract it
+ P := mrp.A.Add(mrp.S.Mult(cx)).Add(tmp1).Add(tmp2).Add(EC.H.Mult(mrp.Mu).Neg())
+ //fmt.Println(P)
+
+ if !InnerProductVerifyFast(mrp.Th, P, EC.U, EC.BPG, HPrime, mrp.IPP) {
+ log.Debug("Range proof failed!")
+ return false
+ }
+
+ return true
+}
+
+// NewECPrimeGroupKey returns the curve (field),
+// Generator 1 x&y, Generator 2 x&y, order of the generators
+func NewECPrimeGroupKey(n int) CryptoParams {
+ curValue := btcec.S256().Gx
+ s256 := sha256.New()
+ gen1Vals := make([]ECPoint, n)
+ gen2Vals := make([]ECPoint, n)
+ u := ECPoint{big.NewInt(0), big.NewInt(0)}
+ cg := ECPoint{}
+ ch := ECPoint{}
+
+ j := 0
+ confirmed := 0
+ for confirmed < (2*n + 3) {
+ s256.Write(new(big.Int).Add(curValue, big.NewInt(int64(j))).Bytes())
+
+ potentialXValue := make([]byte, 33)
+ binary.LittleEndian.PutUint32(potentialXValue, 2)
+ for i, elem := range s256.Sum(nil) {
+ potentialXValue[i+1] = elem
+ }
+
+ gen2, err := btcec.ParsePubKey(potentialXValue, btcec.S256())
+ if err == nil {
+ if confirmed == 2*n { // once we've generated all g and h values then assign this to u
+ u = ECPoint{gen2.X, gen2.Y}
+ //fmt.Println("Got that U value")
+ } else if confirmed == 2*n+1 {
+ cg = ECPoint{gen2.X, gen2.Y}
+
+ } else if confirmed == 2*n+2 {
+ ch = ECPoint{gen2.X, gen2.Y}
+ } else {
+ if confirmed%2 == 0 {
+ gen1Vals[confirmed/2] = ECPoint{gen2.X, gen2.Y}
+ //fmt.Println("new G Value")
+ } else {
+ gen2Vals[confirmed/2] = ECPoint{gen2.X, gen2.Y}
+ //fmt.Println("new H value")
+ }
+ }
+ confirmed += 1
+ }
+ j += 1
+ }
+
+ return CryptoParams{
+ btcec.S256(),
+ btcec.S256(),
+ gen1Vals,
+ gen2Vals,
+ btcec.S256().N,
+ u,
+ n,
+ cg,
+ ch}
+}
+
+func genECPrimeGroupKey(n int) CryptoParams {
+ // curValue := btcec.S256().Gx
+ // s256 := sha256.New()
+ gen1Vals := make([]ECPoint, n)
+ gen2Vals := make([]ECPoint, n)
+ // u := ECPoint{big.NewInt(0), big.NewInt(0)}
+ hx, _ := new(big.Int).SetString("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0", 16)
+ hy, _ := new(big.Int).SetString("31d3c6863973926e049e637cb1b5f40a36dac28af1766968c30c2313f3a38904", 16)
+ ch := ECPoint{hx, hy}
+
+ gx, _ := new(big.Int).SetString("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 16)
+ gy, _ := new(big.Int).SetString("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16)
+ cg := ECPoint{gx, gy}
+
+ i := 0
+ for i < n {
+ gen2Vals[i] = ch.Mult(
+ big.NewInt(int64(i*2 + 1)),
+ )
+ gen1Vals[i] = cg.Mult(
+ big.NewInt(int64(i*2 + 2)),
+ )
+ i++
+ }
+
+ u := cg.Mult(
+ big.NewInt(int64(n + 3)),
+ )
+
+ return CryptoParams{
+ btcec.S256(),
+ btcec.S256(),
+ gen1Vals,
+ gen2Vals,
+ btcec.S256().N,
+ u,
+ n,
+ ch,
+ cg}
+}
+
+func init() {
+ // just need the base parameter N, P, G, H for this init, ignore everything else
+ EC = CryptoParams{
+ btcec.S256(),
+ btcec.S256(),
+ make([]ECPoint, VecLength),
+ make([]ECPoint, VecLength),
+ btcec.S256().N,
+ ECPoint{big.NewInt(0), big.NewInt(0)},
+ VecLength,
+ ECPoint{big.NewInt(0), big.NewInt(0)},
+ ECPoint{big.NewInt(0), big.NewInt(0)}}
+}
diff --git a/core/vm/privacy/bulletproof.json b/core/vm/privacy/bulletproof.json
new file mode 100644
index 0000000000..263dd79270
--- /dev/null
+++ b/core/vm/privacy/bulletproof.json
@@ -0,0 +1 @@
+{"Ipp":{"L":[{"x":"7be22788517d8c7e149727c5397cf7b2d6713546dee4f974f3239a1f53e64f44","y":"b18c08695e40b801ace64f00bf7010245dcf972cad7ce1e97e441fa68575bb72"},{"x":"29956e85820c1ede4f6ec987b3c20cbf7c0fc0aa6a8cd823e73105fc681c1880","y":"228e434578a40d247a2b5f1c2a7a5154716fb06e98d8087b3dce9cc85429b72c"},{"x":"b39703b5680857d7629a39374451baae59459418c23f44f522838efd952e69db","y":"60033aa9807a0c081c530c30292eca71f61e17433513ead9caadce7997d97981"},{"x":"074cd428559b2bf9c0a6d54479254bdeedc26e655b7f0d822aec9a6d1f1068b3","y":"915958a8e24fefe8ec5e6338661567c8e6178d03ac35422284701bf2ab37d592"},{"x":"80d27e070c49f6d41d49254295a9e70ebaf82d8780c93f1c48f018609e3822dd","y":"5c5e365b72835ff1e24ff3a130e1cc332e36d891ba383752e469a667ecf5db01"},{"x":"6e9c63c3188c29d593417b5cb96ab0f149d905a194ace7a3e523d15f8f8922cd","y":"a91566f2cae911542a0658f63451b4a87cea5c668ab4220c974a640442021da6"}],"R":[{"x":"34f512b1fe0989ce77f8cb5b3a95dd31b55c38d4b6278e4923d6cf224d59c421","y":"8757d403eb39a181418db28f742f0ff3f59991929800c424ebce792f27353335"},{"x":"900bc03a4e26a61bb11de434ee150970a22dce77320b26fea1b172dbdfef5b10","y":"de9d1b833decc36f84ae4ce1be87414674ebef7b58009563f35a722347eb76d7"},{"x":"0ca13ff9d0a929b417a165ceb42c532dd54c34e8f1e9083208630dadafdb5ee4","y":"0bba4e3ac3b20cde8074d4683742f924bdb070a590c1d9d7c8f239748359015c"},{"x":"c29728cbb8393b65f8f224e587eccee9d332d2936b36bb460a9f9df720ef5add","y":"88295fbbe05f25534a43ac528a890b9a26ab3bf95a63e4803168d56b430190ce"},{"x":"4cd804793a0169e0bfe1206907cec530a733efb7cca86f08bff8d04bfb82394b","y":"453594ec2090934e75348db0db070c79b6302cf289d1907adbc198493fee417e"},{"x":"9d9a42ba4b30cc68841ce6528f0d4ffa7990b35fc533f7cb0e4bf0d26cc9c6b6","y":"d6dbdb179262c2bc1fc734d4e20a2c54c5e0b8b8d0c48ee630e146f4cef1f486"}],"A":"-2d23144bda297742e1eafb40911ccdbf2f5e950e8b73b4eaf8f78b857d5c7a93","B":"162325c6d1160e0c033135e32b57351c17ef79755cf4f19c6d6c0ba8117e8d09","Challenges":["139fb4a37d387933e43987862d67297c65af5302c6995bfe7181646dcfc169f1","d43aa9b8fdd97b12e3c4bfabf4c36c59dabb08ace9d5da221f676cc7244000e0","3013fdc8605a4dd479898c2b9abbab45ed9b9676267d8c86a0b7b737448c3d8e","b7a16a537783cd7a9e5bddad4536754a6b16a152fedd2df46a36f76a51cd66d9","5408a38e71aa569b6ddc2ccc84a3b2fa29253905072bf8ed5035406cda89e6fa","1ab61f234a5982567e51af82efd118ebcb44befabfaa5f07183471508e3f4208","3e666d903ccd1312a9a83506b298dfac2c2f11f796087d91104487a577802faa"]},"Comms":["71a29edddcf580c0ab4c992f34df4bcd7f23079bf29c07267e354c0e1b0c7b7d0d7d7f55259df2570dc37a2b6719eb58b2195f06163d29b7aca710cbf9b66560"],"A":"e7d28764b37d275ee1b0cc589ab2aa46cc60a406d6cb0def47dcb5fc49b3279dc65b2eb160328db9dc5953a263a5eba0855b51c66a5e23ac0a3b997d060643ed","S":"78aa79b16298d8c7cc587c8fe521d13b9c768256a8842e74e82970507efea3b9735e4324787071ded1e049c888aee40fe85cff0fff4ffdc4d2d3dc2a17ac306a","cy":"3e38e29bf805dc855b687f969a1a854a0c23fddb8ff1f480079929518e8df1f6","cz":"d794749e1c1442762943a40422a6f9bd284f938fce652c382fea05a0e33ca68f","T1":"45e56a5bc134b7b19d53670d57b45874a01442b58a853dd0960f4a7ec1a093f59be5d93e35a55f2006f03cf9c31801942d9a8739a9408c67d93c4dff6c9f7346","T2":"ad380e6564ae44cd6f91656e66c031cfe21aa47cc511ae51e4a2a8604bd181cd181be8eb1b8e0de71458eed4ce538667a392cc0e7c4e85ab7f4cff54161c8087","cx":"75327f647ab5124eefa92e51f769cdb64a24fe5f88a059b002f2d590c9236894","Th":"-ee380a27a0b95643f9a3a5a975c9b35638ba2a7105a36c7ffd90acdd16029323","Tau":"38059dcf3dfc1da9646f3dc66c8b1487c3375577e751e8341b2addd45ef06306","Mu":"e648b63a1857d1e9723b01ac3151c29fd723845f8aa2a7d6ae867feba8db53e5"}
\ No newline at end of file
diff --git a/core/vm/privacy/bulletproof_test.go b/core/vm/privacy/bulletproof_test.go
new file mode 100644
index 0000000000..54f67c080a
--- /dev/null
+++ b/core/vm/privacy/bulletproof_test.go
@@ -0,0 +1,525 @@
+package privacy
+
+import (
+ "crypto/rand"
+ "encoding/json"
+ "fmt"
+ "github.com/stretchr/testify/assert"
+ "io/ioutil"
+ "math/big"
+ "os"
+ "testing"
+)
+
+func TestInnerProductProveLen1(t *testing.T) {
+ fmt.Println("TestInnerProductProve1")
+ EC = genECPrimeGroupKey(1)
+ a := make([]*big.Int, 1)
+ b := make([]*big.Int, 1)
+
+ a[0] = big.NewInt(1)
+
+ b[0] = big.NewInt(1)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductProveLen2(t *testing.T) {
+ fmt.Println("TestInnerProductProve2")
+ EC = genECPrimeGroupKey(2)
+ a := make([]*big.Int, 2)
+ b := make([]*big.Int, 2)
+
+ a[0] = big.NewInt(1)
+ a[1] = big.NewInt(1)
+
+ b[0] = big.NewInt(1)
+ b[1] = big.NewInt(1)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ fmt.Println("P after two vector commitment with gen ", P)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductProveLen4(t *testing.T) {
+ fmt.Println("TestInnerProductProve4")
+ EC = genECPrimeGroupKey(4)
+ a := make([]*big.Int, 4)
+ b := make([]*big.Int, 4)
+
+ a[0] = big.NewInt(1)
+ a[1] = big.NewInt(1)
+ a[2] = big.NewInt(1)
+ a[3] = big.NewInt(1)
+
+ b[0] = big.NewInt(1)
+ b[1] = big.NewInt(1)
+ b[2] = big.NewInt(1)
+ b[3] = big.NewInt(1)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductProveLen8(t *testing.T) {
+ fmt.Println("TestInnerProductProve8")
+ EC = genECPrimeGroupKey(8)
+ a := make([]*big.Int, 8)
+ b := make([]*big.Int, 8)
+
+ a[0] = big.NewInt(1)
+ a[1] = big.NewInt(1)
+ a[2] = big.NewInt(1)
+ a[3] = big.NewInt(1)
+ a[4] = big.NewInt(1)
+ a[5] = big.NewInt(1)
+ a[6] = big.NewInt(1)
+ a[7] = big.NewInt(1)
+
+ b[0] = big.NewInt(2)
+ b[1] = big.NewInt(2)
+ b[2] = big.NewInt(2)
+ b[3] = big.NewInt(2)
+ b[4] = big.NewInt(2)
+ b[5] = big.NewInt(2)
+ b[6] = big.NewInt(2)
+ b[7] = big.NewInt(2)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductProveLen64Rand(t *testing.T) {
+ fmt.Println("TestInnerProductProveLen64Rand")
+ EC = genECPrimeGroupKey(64)
+ a := RandVector(64)
+ b := RandVector(64)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ fmt.Printf("Values Used: \n\ta = %s\n\tb = %s\n", a, b)
+ }
+
+}
+
+func TestInnerProductVerifyFastLen1(t *testing.T) {
+ fmt.Println("TestInnerProductProve1")
+ EC = genECPrimeGroupKey(1)
+ a := make([]*big.Int, 1)
+ b := make([]*big.Int, 1)
+
+ a[0] = big.NewInt(2)
+
+ b[0] = big.NewInt(2)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductVerifyFastLen2(t *testing.T) {
+ fmt.Println("TestInnerProductProve2")
+ EC = genECPrimeGroupKey(2)
+ a := make([]*big.Int, 2)
+ b := make([]*big.Int, 2)
+
+ a[0] = big.NewInt(2)
+ a[1] = big.NewInt(3)
+
+ b[0] = big.NewInt(2)
+ b[1] = big.NewInt(3)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductVerifyFastLen4(t *testing.T) {
+ fmt.Println("TestInnerProductProve4")
+ EC = genECPrimeGroupKey(4)
+ a := make([]*big.Int, 4)
+ b := make([]*big.Int, 4)
+
+ a[0] = big.NewInt(1)
+ a[1] = big.NewInt(1)
+ a[2] = big.NewInt(1)
+ a[3] = big.NewInt(1)
+
+ b[0] = big.NewInt(1)
+ b[1] = big.NewInt(1)
+ b[2] = big.NewInt(1)
+ b[3] = big.NewInt(1)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductVerifyFastLen8(t *testing.T) {
+ fmt.Println("TestInnerProductProve8")
+ EC = genECPrimeGroupKey(8)
+ a := make([]*big.Int, 8)
+ b := make([]*big.Int, 8)
+
+ a[0] = big.NewInt(1)
+ a[1] = big.NewInt(1)
+ a[2] = big.NewInt(1)
+ a[3] = big.NewInt(1)
+ a[4] = big.NewInt(1)
+ a[5] = big.NewInt(1)
+ a[6] = big.NewInt(1)
+ a[7] = big.NewInt(1)
+
+ b[0] = big.NewInt(2)
+ b[1] = big.NewInt(2)
+ b[2] = big.NewInt(2)
+ b[3] = big.NewInt(2)
+ b[4] = big.NewInt(2)
+ b[5] = big.NewInt(2)
+ b[6] = big.NewInt(2)
+ b[7] = big.NewInt(2)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ }
+}
+
+func TestInnerProductVerifyFastLen64Rand(t *testing.T) {
+ fmt.Println("TestInnerProductProveLen64Rand")
+ EC = genECPrimeGroupKey(64)
+ a := RandVector(64)
+ b := RandVector(64)
+
+ c := InnerProduct(a, b)
+
+ P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
+
+ ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
+
+ if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
+ fmt.Println("Inner Product Proof correct")
+ } else {
+ t.Error("Inner Product Proof incorrect")
+ fmt.Printf("Values Used: \n\ta = %s\n\tb = %s\n", a, b)
+ }
+
+}
+
+func TestMRPProveZERO(t *testing.T) {
+
+ mRangeProof, _ := MRPProve([]*big.Int{
+ new(big.Int).SetInt64(0),
+ })
+ mv := MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+}
+
+func TestMRPProve_MAX_2_POW_64(t *testing.T) {
+
+ mRangeProof, _ := MRPProve([]*big.Int{
+ new(big.Int).SetUint64(0xFFFFFFFFFFFFFFFF),
+ })
+ mv := MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+}
+
+func TestMRPProveOutOfSupportedRange(t *testing.T) {
+
+ value, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFF", 16)
+ _, err := MRPProve([]*big.Int{
+ value,
+ })
+ assert.NotNil(t, err, " MRProof incorrect")
+}
+
+func TestMRPProve_RANDOM(t *testing.T) {
+
+ mRangeProof, _ := MRPProve(Rand64Vector(1))
+ mv := MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+
+ mRangeProof, _ = MRPProve(Rand64Vector(2))
+ mv = MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+
+ mRangeProof, _ = MRPProve(Rand64Vector(4))
+ mv = MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+
+ mRangeProof, _ = MRPProve(Rand64Vector(8))
+ mv = MRPVerify(&mRangeProof)
+ assert.Equal(t, mv, true, " MRProof incorrect")
+}
+
+func Rand64Vector(l int) []*big.Int {
+ result := make([]*big.Int, l)
+
+ for i := 0; i < l; i++ {
+ x, err := rand.Int(rand.Reader, big.NewInt(0xFFFFFFFFFFFFFFF))
+ check(err)
+ result[i] = x
+ }
+
+ return result
+}
+
+func TestMRPProveValueNumberNotSupported(t *testing.T) {
+
+ _, err := MRPProve(Rand64Vector(3))
+ assert.NotNil(t, err, "MRProof incorrect - accepted 3 inputs")
+
+ _, err = MRPProve(Rand64Vector(5))
+ assert.NotNil(t, err, "MRProof incorrect - accepted 5 inputs")
+
+ _, err = MRPProve(Rand64Vector(6))
+ assert.NotNil(t, err, "MRProof incorrect - accepted 6 inputs")
+
+ _, err = MRPProve(Rand64Vector(7))
+ assert.NotNil(t, err, "MRProof incorrect - accepted 7 inputs")
+
+ _, err = MRPProve(Rand64Vector(10))
+ assert.NotNil(t, err, "MRProof incorrect - accepted 10 inputs")
+
+ _, err = MRPProve(Rand64Vector(1))
+ assert.Nil(t, err, "MRProof incorrect - not accepted 1 inputs")
+
+ _, err = MRPProve(Rand64Vector(2))
+ assert.Nil(t, err, "MRProof incorrect - not accepted 2 inputs")
+
+ _, err = MRPProve(Rand64Vector(4))
+ fmt.Println(err)
+ assert.Nil(t, err, "MRProof incorrect - not accepted 4 inputs")
+
+ _, err = MRPProve(Rand64Vector(8))
+ assert.Nil(t, err, "MRProof incorrect - not accepted 8 inputs")
+}
+
+type Point struct {
+ x string
+ y string
+}
+
+type IPP struct {
+ L []map[string]string `json:"L"`
+ R []map[string]string `json:"R"`
+ A string `json:"A"`
+ B string `json:"B"`
+ Challenges []string `json:"Challenges"`
+}
+
+type BulletProof struct {
+ Comms []string `json:"Comms"`
+ A string `json:"A"`
+ S string `json:"S"`
+ Cx string `json:"Cx"`
+ Cy string `json:"Cy"`
+ Cz string `json:"Cz"`
+ T1 string `json:"T1"`
+ T2 string `json:"T2"`
+ Th string `json:"Th"`
+ Tau string `json:"Tau"`
+ Mu string `json:"Mu"`
+ Ipp IPP `json:"Ipp"`
+}
+
+func parseTestData(filePath string) MultiRangeProof {
+ jsonFile, err := os.Open(filePath)
+
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ defer jsonFile.Close()
+
+ byteValue, _ := ioutil.ReadAll(jsonFile)
+
+ // we initialize our Users array
+ // var result map[string]interface{}
+ result := BulletProof{}
+
+ json.Unmarshal([]byte(byteValue), &result)
+
+ fmt.Println("result ", result.Tau)
+ fmt.Println("result ", result.Th)
+ fmt.Println("result.Ipp ", result.Ipp)
+
+ ipp := result.Ipp
+
+ proof := MultiRangeProof{
+ Comms: MapECPointFromHex(result.Comms, ECPointFromHex),
+ A: ECPointFromHex(result.A),
+ S: ECPointFromHex(result.S),
+ T1: ECPointFromHex(result.T1),
+ T2: ECPointFromHex(result.T2),
+ Th: bigIFromHex(result.Th),
+ Tau: bigIFromHex(result.Tau),
+ Mu: bigIFromHex(result.Mu),
+ Cx: bigIFromHex(result.Cx),
+ Cy: bigIFromHex(result.Cy),
+ Cz: bigIFromHex(result.Cz),
+ IPP: InnerProdArg{
+ L: MapECPoint(ipp.L, ECPointFromPoint),
+ R: MapECPoint(ipp.R, ECPointFromPoint),
+ A: bigIFromHex(ipp.A),
+ B: bigIFromHex(ipp.B),
+ Challenges: MapBigI(ipp.Challenges, bigIFromHex),
+ },
+ }
+
+ fmt.Println(proof)
+ return proof
+}
+
+/**
+Utils for parsing data from json
+*/
+func MapBigI(list []string, f func(string) *big.Int) []*big.Int {
+ result := make([]*big.Int, len(list))
+
+ for i, item := range list {
+ result[i] = f(item)
+ }
+ return result
+}
+
+func MapECPointFromHex(list []string, f func(string) ECPoint) []ECPoint {
+ result := make([]ECPoint, len(list))
+
+ for i, item := range list {
+ result[i] = f(item)
+ }
+ return result
+}
+
+func MapECPoint(list []map[string]string, f func(Point) ECPoint) []ECPoint {
+ result := make([]ECPoint, len(list))
+
+ for i, item := range list {
+ result[i] = f(Point{
+ x: item["x"],
+ y: item["y"],
+ })
+ }
+ return result
+}
+
+func bigIFromHex(hex string) *big.Int {
+ tmp, _ := new(big.Int).SetString(hex, 16)
+ return tmp
+}
+
+func ECPointFromHex(hex string) ECPoint {
+ Px, _ := new(big.Int).SetString(hex[:64], 16)
+ Py, _ := new(big.Int).SetString(hex[64:], 16)
+ P := ECPoint{Px, Py}
+ return P
+}
+
+func ECPointFromPoint(ecpoint Point) ECPoint {
+ Px, _ := new(big.Int).SetString(ecpoint.x, 16)
+ Py, _ := new(big.Int).SetString(ecpoint.y, 16)
+ P := ECPoint{Px, Py}
+ return P
+}
+
+func TestMRPGeneration(t *testing.T) {
+ values := make([]*big.Int, 2)
+ values[0] = big.NewInt(1000)
+ values[1] = big.NewInt(100000)
+ mrp, err := MRPProve(values)
+ if err != nil {
+ t.Error("failed to generate bulletproof")
+ }
+
+ v := MRPVerify(&mrp)
+ serilizedBp := mrp.Serialize()
+
+ newMRP := new(MultiRangeProof)
+ if newMRP.Deserialize(serilizedBp) != nil {
+ t.Error("failed to deserialized bulletproof")
+ }
+
+ v = v && MRPVerify(newMRP)
+
+ if !v {
+ t.Error("failed to verify bulletproof")
+ }
+}
diff --git a/core/vm/privacy/ringct.go b/core/vm/privacy/ringct.go
new file mode 100644
index 0000000000..cc6e3e492b
--- /dev/null
+++ b/core/vm/privacy/ringct.go
@@ -0,0 +1,600 @@
+package privacy
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "math/big"
+
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/log"
+)
+
+// These constants define the lengths of serialized public keys.
+const (
+ PubKeyBytesLenCompressed = 33
+ PubKeyBytesLenUncompressed = 65
+ PubKeyBytesLenHybrid = 65
+)
+
+const (
+ pubkeyCompressed byte = 0x2 // y_bit + x coord
+ pubkeyUncompressed byte = 0x4 // x coord + y coord
+ pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
+)
+
+//The proof contains pretty much stuffs
+//The proof contains pretty much stuffs
+//Ring size rs: 1 byte => proof[0]
+//num input: number of real inputs: 1 byte => proof[1]
+//List of inputs/UTXO index typed uint64 => total size = rs * numInput * 8 = proof[0]*proof[1]*8
+//List of key images: total size = numInput * 33 = proof[1] * 33
+//number of output n: 1 byte
+//List of output => n * 130 bytes
+//transaction fee: uint256 => 32 byte
+//ringCT proof size ctSize: uint16 => 2 byte
+//ringCT proof: ctSize bytes
+//bulletproofs: bp
+type PrivateSendVerifier struct {
+ proof []byte
+ //ringCT RingCT
+}
+
+type Ring []*ecdsa.PublicKey
+
+type RingSignature struct {
+ NumRing int
+ Size int // size of ring
+ M [32]byte // message
+ C *big.Int // ring signature value, 1 element
+ S [][]*big.Int // ring signature values: [NumRing][Size]
+ Ring []Ring // array of rings of pubkeys: [NumRing]
+ I []*ecdsa.PublicKey // key images, size = the number of rings [NumRing]
+ Curve elliptic.Curve
+ SerializedRing []byte //temporary memory stored the raw ring ct used in case of verifying ringCT with message verification
+}
+
+func (p *PrivateSendVerifier) verify() bool {
+ return false
+}
+
+func (p *PrivateSendVerifier) deserialize() {
+
+}
+
+// helper function, returns type of v
+func typeof(v interface{}) string {
+ return fmt.Sprintf("%T", v)
+}
+
+func isOdd(a *big.Int) bool {
+ return a.Bit(0) == 1
+}
+
+// SerializeCompressed serializes a public key in a 33-byte compressed format.
+func SerializeCompressed(p *ecdsa.PublicKey) []byte {
+ b := make([]byte, 0, PubKeyBytesLenCompressed)
+ format := pubkeyCompressed
+ if isOdd(p.Y) {
+ format |= 0x1
+ }
+ b = append(b, format)
+ return append(b, PadTo32Bytes(p.X.Bytes())...)
+}
+
+func DeserializeCompressed(curve elliptic.Curve, b []byte) *ecdsa.PublicKey {
+ x := new(big.Int).SetBytes(b[1:33])
+ // Y = +-sqrt(x^3 + B)
+ x3 := new(big.Int).Mul(x, x)
+ x3.Mul(x3, x)
+ x3.Add(x3, curve.Params().B)
+
+ // now calculate sqrt mod p of x2 + B
+ // This code used to do a full sqrt based on tonelli/shanks,
+ // but this was replaced by the algorithms referenced in
+ // https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
+ PPlus1Div4 := new(big.Int).Add(curve.Params().P, big.NewInt(1))
+ PPlus1Div4 = PPlus1Div4.Div(PPlus1Div4, big.NewInt(4))
+ y := new(big.Int).Exp(x3, PPlus1Div4, curve.Params().P)
+ ybit := b[0]%2 == 1
+ if ybit != isOdd(y) {
+ y.Sub(curve.Params().P, y)
+ }
+ if ybit != isOdd(y) {
+ return nil
+ }
+ return &ecdsa.PublicKey{curve, x, y}
+}
+
+// bytes returns the public key ring as a byte slice.
+func (r Ring) Bytes() (b []byte) {
+ for _, pub := range r {
+ b = append(b, PadTo32Bytes(pub.X.Bytes())...)
+ b = append(b, PadTo32Bytes(pub.Y.Bytes())...)
+ }
+ return
+}
+
+func PadTo32Bytes(in []byte) (out []byte) {
+ out = append(out, in...)
+ for {
+ if len(out) == 32 {
+ return
+ }
+ out = append([]byte{0}, out...)
+ }
+}
+
+// converts the signature to a byte array
+// this is the format that will be used when passing EVM bytecode
+func (r *RingSignature) Serialize() ([]byte, error) {
+ sig := []byte{}
+ // add size and message
+ b := make([]byte, 8)
+ binary.BigEndian.PutUint64(b, uint64(r.NumRing))
+ sig = append(sig, b[:]...) // 8 bytes
+
+ b = make([]byte, 8)
+ binary.BigEndian.PutUint64(b, uint64(r.Size))
+ sig = append(sig, b[:]...) // 8 bytes
+
+ sig = append(sig, PadTo32Bytes(r.M[:])...) // 32 bytes
+ sig = append(sig, PadTo32Bytes(r.C.Bytes())...) // 32 bytes
+
+ for k := 0; k < r.NumRing; k++ {
+ // 96 bytes each iteration
+ for i := 0; i < r.Size; i++ {
+ sig = append(sig, PadTo32Bytes(r.S[k][i].Bytes())...)
+ }
+ }
+ for k := 0; k < r.NumRing; k++ {
+ // 96 bytes each iteration
+ for i := 0; i < r.Size; i++ {
+ rb := SerializeCompressed(r.Ring[k][i])
+ sig = append(sig, rb...)
+ }
+ }
+
+ for k := 0; k < r.NumRing; k++ {
+ // 64 bytes
+ rb := SerializeCompressed(r.I[k])
+ sig = append(sig, rb...)
+ }
+
+ if len(sig) != 8+8+32+32+(32+33)*r.NumRing*r.Size+33*r.NumRing {
+ return []byte{}, errors.New("Could not serialize ring signature")
+ }
+
+ return sig, nil
+}
+
+func computeSignatureSize(numRing int, ringSize int) int {
+ return 8 + 8 + 32 + 32 + numRing*ringSize*32 + numRing*ringSize*33 + numRing*33
+}
+
+// deserializes the byteified signature into a RingSignature struct
+func Deserialize(r []byte) (*RingSignature, error) {
+ if len(r) < 16 {
+ return nil, errors.New("Failed to deserialize ring signature")
+ }
+ offset := 0
+ sig := new(RingSignature)
+ numRing := r[offset : offset+8]
+ offset += 8
+ size := r[offset : offset+8]
+ offset += 8
+
+ size_uint := binary.BigEndian.Uint64(size)
+ size_int := int(size_uint)
+ sig.Size = size_int
+
+ size_uint = binary.BigEndian.Uint64(numRing)
+ size_int = int(size_uint)
+ sig.NumRing = size_int
+
+ if len(r) != computeSignatureSize(sig.NumRing, sig.Size) {
+ return nil, errors.New("incorrect ring size")
+ }
+
+ m := r[offset : offset+32]
+ offset += 32
+
+ var m_byte [32]byte
+ copy(m_byte[:], m)
+
+ sig.M = m_byte
+ sig.C = new(big.Int).SetBytes(r[offset : offset+32])
+ offset += 32
+
+ sig.S = make([][]*big.Int, sig.NumRing)
+ for i := 0; i < sig.NumRing; i++ {
+ sig.S[i] = make([]*big.Int, sig.Size)
+ for j := 0; j < sig.Size; j++ {
+ sig.S[i][j] = new(big.Int).SetBytes(r[offset : offset+32])
+ offset += 32
+ }
+ }
+
+ sig.Curve = crypto.S256()
+
+ sig.Ring = make([]Ring, sig.NumRing)
+ for i := 0; i < sig.NumRing; i++ {
+ sig.Ring[i] = make([]*ecdsa.PublicKey, sig.Size)
+ for j := 0; j < sig.Size; j++ {
+ compressedKey := r[offset : offset+33]
+ offset += 33
+ compressedPubKey := DeserializeCompressed(sig.Curve, compressedKey)
+ sig.Ring[i][j] = compressedPubKey
+ }
+ }
+
+ sig.I = make([]*ecdsa.PublicKey, sig.NumRing)
+ for i := 0; i < sig.NumRing; i++ {
+ compressedKey := r[offset : offset+33]
+ offset += 33
+ compressedPubKey := DeserializeCompressed(sig.Curve, compressedKey)
+ sig.I[i] = compressedPubKey
+ }
+
+ sig.SerializedRing = r
+
+ return sig, nil
+}
+
+// takes public key ring and places the public key corresponding to `privkey` in index s of the ring
+// returns a key ring of type []*ecdsa.PublicKey
+func GenKeyRing(ring []*ecdsa.PublicKey, privkey *ecdsa.PrivateKey, s int) ([]*ecdsa.PublicKey, error) {
+ size := len(ring) + 1
+ new_ring := make([]*ecdsa.PublicKey, size)
+ pubkey := privkey.Public().(*ecdsa.PublicKey)
+
+ if s > len(ring) {
+ return nil, errors.New("index s out of bounds")
+ }
+
+ new_ring[s] = pubkey
+ for i := 1; i < size; i++ {
+ idx := (i + s) % size
+ new_ring[idx] = ring[i-1]
+ }
+
+ return new_ring, nil
+}
+
+// creates a ring with size specified by `size` and places the public key corresponding to `privkey` in index s of the ring
+// returns a new key ring of type []*ecdsa.PublicKey
+func GenNewKeyRing(size int, privkey *ecdsa.PrivateKey, s int) ([]*ecdsa.PublicKey, error) {
+ ring := make([]*ecdsa.PublicKey, size)
+ pubkey := privkey.Public().(*ecdsa.PublicKey)
+
+ if s > len(ring) {
+ return nil, errors.New("index s out of bounds")
+ }
+
+ ring[s] = pubkey
+
+ for i := 1; i < size; i++ {
+ idx := (i + s) % size
+ priv, err := crypto.GenerateKey()
+ if err != nil {
+ return nil, err
+ }
+
+ pub := priv.Public()
+ ring[idx] = pub.(*ecdsa.PublicKey)
+ }
+
+ return ring, nil
+}
+
+// calculate key image I = x * H_p(P) where H_p is a hash function that returns a point
+// H_p(P) = sha3(P) * G
+func GenKeyImage(privkey *ecdsa.PrivateKey) *ecdsa.PublicKey {
+ pubkey := privkey.Public().(*ecdsa.PublicKey)
+ image := new(ecdsa.PublicKey)
+
+ // calculate sha3(P)
+ h_x, h_y := HashPoint(pubkey)
+
+ // calculate H_p(P) = x * sha3(P) * G
+ i_x, i_y := privkey.Curve.ScalarMult(h_x, h_y, privkey.D.Bytes())
+
+ image.X = i_x
+ image.Y = i_y
+ return image
+}
+
+func HashPoint(p *ecdsa.PublicKey) (*big.Int, *big.Int) {
+ input := append(PadTo32Bytes(p.X.Bytes()), PadTo32Bytes(p.Y.Bytes())...)
+ log.Info("HashPoint", "input ", common.Bytes2Hex(input))
+ hash := crypto.Keccak256(input)
+ log.Info("HashPoint", "hash ", common.Bytes2Hex(hash))
+ return p.Curve.ScalarBaseMult(hash[:])
+}
+
+// create ring signature from list of public keys given inputs:
+// msg: byte array, message to be signed
+// ring: array of *ecdsa.PublicKeys to be included in the ring
+// privkey: *ecdsa.PrivateKey of signer
+// s: index of signer in ring
+func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingSignature, error) {
+ numRing := len(rings)
+ if numRing < 1 {
+ return nil, errors.New("there is no ring to make signature")
+ }
+ // check ringsize > 1
+ ringsize := len(rings[0])
+ if ringsize < 2 {
+ return nil, errors.New("size of ring less than two")
+ } else if s >= ringsize || s < 0 {
+ return nil, errors.New("secret index out of range of ring size")
+ }
+
+ // setup
+ //pubkey := privkey.Public().(*ecdsa.PublicKey)
+ pubkeys := make([]*ecdsa.PublicKey, numRing)
+ for i := 0; i < numRing; i++ {
+ pubkeys[i] = &privkeys[i].PublicKey
+ }
+ curve := pubkeys[0].Curve
+ sig := new(RingSignature)
+ sig.Size = ringsize
+ sig.NumRing = numRing
+ sig.M = m
+ sig.Ring = rings
+ sig.Curve = curve
+
+ // check that key at index s is indeed the signer
+ for i := 0; i < numRing; i++ {
+ if rings[i][s] != pubkeys[i] {
+ return nil, errors.New("secret index in ring is not signer")
+ }
+ }
+
+ // generate key image
+ images := make([]*ecdsa.PublicKey, numRing)
+ for i := 0; i < numRing; i++ {
+ images[i] = GenKeyImage(privkeys[i])
+ }
+ sig.I = images
+
+ // start at c[1]
+ // pick random scalar u (glue value), calculate c[1] = H(m, u*G) where H is a hash function and G is the base point of the curve
+ C := make([]*big.Int, ringsize)
+ S := make([][]*big.Int, numRing)
+ for i := 0; i < numRing; i++ {
+ S[i] = make([]*big.Int, ringsize)
+ }
+
+ //Initialize S except S[..][s]
+ for i := 0; i < numRing; i++ {
+ for j := 0; j < ringsize; j++ {
+ if j != s {
+ randomGenerated, err := rand.Int(rand.Reader, curve.Params().P)
+ if err != nil {
+ return nil, err
+ }
+ S[i][j] = randomGenerated
+ }
+ }
+ }
+
+ L := make([][]*ecdsa.PublicKey, numRing)
+ R := make([][]*ecdsa.PublicKey, numRing)
+ for i := 0; i < numRing; i++ {
+ L[i] = make([]*ecdsa.PublicKey, ringsize)
+ R[i] = make([]*ecdsa.PublicKey, ringsize)
+ }
+ alpha := make([]*big.Int, numRing)
+
+ var l []byte
+ //compute L[i][s], R[i][s], i = 0..numRing
+ for i := 0; i < numRing; i++ {
+ randomGenerated, err := rand.Int(rand.Reader, curve.Params().P)
+ if err != nil {
+ return nil, err
+ }
+ alpha[i] = randomGenerated
+ // start at secret index s/PI
+ // compute L_s = u*G
+ l_x, l_y := curve.ScalarBaseMult(PadTo32Bytes(alpha[i].Bytes()))
+ L[i][s] = &ecdsa.PublicKey{curve, l_x, l_y}
+ lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
+ l = append(l, lT...)
+ // compute R_s = u*H_p(P[s])
+ h_x, h_y := HashPoint(pubkeys[i])
+ r_x, r_y := curve.ScalarMult(h_x, h_y, PadTo32Bytes(alpha[i].Bytes()))
+ R[i][s] = &ecdsa.PublicKey{curve, r_x, r_y}
+ rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
+ l = append(l, rT...)
+ }
+
+ // concatenate m and u*G and calculate c[s+1] = H(m, L_s, R_s)
+ C_j := crypto.Keccak256(append(m[:], l...))
+ idx := s + 1
+ if idx == ringsize {
+ idx = 0
+ }
+ if idx == 0 {
+ C[0] = new(big.Int).SetBytes(C_j[:])
+ } else {
+ C[idx] = new(big.Int).SetBytes(C_j[:])
+ }
+ for idx != s {
+ var l []byte
+ for j := 0; j < numRing; j++ {
+ // calculate L[j][idx] = s[j][idx]*G + c[idx]*Ring[j][idx]
+ px, py := curve.ScalarMult(rings[j][idx].X, rings[j][idx].Y, PadTo32Bytes(C[idx].Bytes())) // px, py = c_i*P_i
+ sx, sy := curve.ScalarBaseMult(PadTo32Bytes(S[j][idx].Bytes())) // sx, sy = s[n-1]*G
+ l_x, l_y := curve.Add(sx, sy, px, py)
+ L[j][idx] = &ecdsa.PublicKey{curve, l_x, l_y}
+ lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
+ l = append(l, lT...)
+
+ // calculate R[j][idx] = s[j][idx]*H_p(Ring[j][idx]) + c[idx]*I[j]
+ px, py = curve.ScalarMult(images[j].X, images[j].Y, C[idx].Bytes()) // px, py = c_i*I
+ hx, hy := HashPoint(rings[j][idx])
+ sx, sy = curve.ScalarMult(hx, hy, S[j][idx].Bytes()) // sx, sy = s[n-1]*H_p(P_i)
+ r_x, r_y := curve.Add(sx, sy, px, py)
+ R[j][idx] = &ecdsa.PublicKey{curve, r_x, r_y}
+ rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
+ l = append(l, rT...)
+ }
+
+ idx++
+ if idx == ringsize {
+ idx = 0
+ }
+
+ var ciIdx int
+ if idx == 0 {
+ ciIdx = 0
+ } else {
+ ciIdx = idx
+ }
+ cSha := crypto.Keccak256(append(PadTo32Bytes(m[:]), l...))
+ C[ciIdx] = new(big.Int).SetBytes(cSha[:])
+ }
+
+ //compute S[j][s] = alpha[j] - c[s] * privkeys[j], privkeys[j] = private key corresponding to key image I[j]
+ for j := 0; j < numRing; j++ {
+ cx := C[s]
+ // close ring by finding S[j][s] = (alpha[j] - c[s]*privkeys[s] ) mod P where k[s] is the private key and P is the order of the curve
+ S[j][s] = new(big.Int).Mod(new(big.Int).Sub(alpha[j], new(big.Int).Mul(cx, privkeys[j].D)), curve.Params().N)
+ }
+
+ // everything ok, add values to signature
+ sig.S = S
+ sig.C = C[0]
+ sig.NumRing = numRing
+ sig.Size = ringsize
+ sig.C = C[0]
+
+ return sig, nil
+}
+
+// verify ring signature contained in RingSignature struct
+// returns true if a valid signature, false otherwise
+func Verify(sig *RingSignature, verifyMes bool) bool {
+ // setup
+ rings := sig.Ring
+ ringsize := sig.Size
+ numRing := sig.NumRing
+ S := sig.S
+ C := make([]*big.Int, ringsize+1)
+ C[0] = sig.C
+ curve := sig.Curve
+ image := sig.I
+
+ // calculate c[i+1] = H(m, s[i]*G + c[i]*P[i])
+ // and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size
+ //log.Info("C", "0", common.Bytes2Hex(C[0].Bytes()))
+ for j := 0; j < ringsize; j++ {
+ var l []byte
+ for i := 0; i < numRing; i++ {
+ // calculate L[i][j] = s[i][j]*G + c[j]*Ring[i][j]
+ px, py := curve.ScalarMult(rings[i][j].X, rings[i][j].Y, C[j].Bytes()) // px, py = c_i*P_i
+ sx, sy := curve.ScalarBaseMult(S[i][j].Bytes()) // sx, sy = s[i]*G
+ l_x, l_y := curve.Add(sx, sy, px, py)
+ lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
+ //log.Info("L[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(lT))
+ l = append(l, lT...)
+
+ // calculate R_i = s[i][j]*H_p(Ring[i][j]) + c[j]*I[j]
+ px, py = curve.ScalarMult(image[i].X, image[i].Y, C[j].Bytes()) // px, py = c[i]*I
+ hx, hy := HashPoint(rings[i][j])
+ //log.Info("H[i][j]", "i", i, "j", j, "x.input", common.Bytes2Hex(rings[i][j].X.Bytes()), "y.input", common.Bytes2Hex(rings[i][j].Y.Bytes()))
+ //log.Info("H[i][j]", "i", i, "j", j, "x", common.Bytes2Hex(hx.Bytes()), "y", common.Bytes2Hex(hy.Bytes()))
+ sx, sy = curve.ScalarMult(hx, hy, S[i][j].Bytes()) // sx, sy = s[i]*H_p(P[i])
+ r_x, r_y := curve.Add(sx, sy, px, py)
+ rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
+ //log.Info("R[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(rT))
+ l = append(l, rT...)
+ }
+
+ // calculate c[i+1] = H(m, L_i, R_i)
+ //cj_mes := append(PadTo32Bytes(sig.M[:]), l...)
+ C_j := crypto.Keccak256(append(PadTo32Bytes(sig.M[:]), l...))
+ //log.Info("C hash input", "j", j + 1, "C_input", common.Bytes2Hex(cj_mes))
+
+ /*if j == ringsize-1 {
+ C[0] = new(big.Int).SetBytes(C_j[:])
+ } else {*/
+ C[j+1] = new(big.Int).SetBytes(C_j[:])
+ //log.Info("C", "j", j + 1, "C", common.Bytes2Hex(C[j + 1].Bytes()))
+ //}
+ }
+
+ return bytes.Equal(sig.C.Bytes(), C[ringsize].Bytes())
+}
+
+func Link(sig_a *RingSignature, sig_b *RingSignature) bool {
+ for i := 0; i < len(sig_a.I); i++ {
+ for j := 0; j < len(sig_b.I); j++ {
+ if sig_a.I[i].X == sig_b.I[j].X && sig_a.I[i].Y == sig_b.I[j].Y {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+//function returns(mutiple rings, private keys, message, error)
+func GenerateMultiRingParams(numRing int, ringSize int, s int) (rings []Ring, privkeys []*ecdsa.PrivateKey, m [32]byte, err error) {
+ for i := 0; i < numRing; i++ {
+ privkey, err := crypto.GenerateKey()
+ if err != nil {
+ return nil, nil, [32]byte{}, err
+ }
+ privkeys = append(privkeys, privkey)
+
+ ring, err := GenNewKeyRing(ringSize, privkey, s)
+ if err != nil {
+ return nil, nil, [32]byte{}, err
+ }
+ rings = append(rings, ring)
+ }
+
+ _, err = rand.Read(m[:])
+ if err != nil {
+ return nil, nil, [32]byte{}, err
+ }
+ return rings, privkeys, m, nil
+}
+
+func TestRingSignature() (bool, []byte) {
+ /*for i := 14; i < 15; i++ {
+ for j := 14; j < 15; j++ {
+ for k := 0; k <= j; k++ {*/
+ numRing := 1
+ ringSize := 10
+ s := 9
+ rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
+ ringSignature, err := Sign(m, rings, privkeys, s)
+ if err != nil {
+ log.Error("Failed to create Ring signature")
+ return false, []byte{}
+ }
+
+ sig, err := ringSignature.Serialize()
+ if err != nil {
+ return false, []byte{}
+ }
+
+ deserializedSig, err := Deserialize(sig)
+ if err != nil {
+ return false, []byte{}
+ }
+ verified := Verify(deserializedSig, false)
+ if !verified {
+ log.Error("Failed to verify Ring signature")
+ return false, []byte{}
+ }
+
+ return true, []byte{}
+}
diff --git a/core/vm/privacy/ringct_test.go b/core/vm/privacy/ringct_test.go
new file mode 100644
index 0000000000..703b08df09
--- /dev/null
+++ b/core/vm/privacy/ringct_test.go
@@ -0,0 +1,46 @@
+package privacy
+
+import (
+ "fmt"
+ "testing"
+ )
+
+func TestSign(t *testing.T) {
+ /*for i := 14; i < 15; i++ {
+ for j := 14; j < 15; j++ {
+ for k := 0; k <= j; k++ {*/
+ numRing := 5
+ ringSize := 10
+ s := 9
+ fmt.Println("Generate random ring parameter ")
+ rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
+
+ fmt.Println("numRing ", numRing)
+ fmt.Println("ringSize ", ringSize)
+ fmt.Println("index of real one ", s)
+
+ fmt.Println("Ring ", rings)
+ fmt.Println("privkeys ", privkeys)
+ fmt.Println("m ", m)
+
+ ringSignature, err := Sign(m, rings, privkeys, s)
+ if err != nil {
+ t.Error("Failed to create Ring signature")
+ }
+
+ sig, err := ringSignature.Serialize()
+ if err != nil {
+ t.Error("Failed to Serialize input Ring signature")
+ }
+
+ deserializedSig, err := Deserialize(sig)
+ if err != nil {
+ t.Error("Failed to Deserialize Ring signature")
+ }
+ verified := Verify(deserializedSig, false)
+
+ if !verified {
+ t.Error("Failed to verify Ring signature")
+ }
+
+}
diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go
index 31c9b9cf9d..24d3a79301 100644
--- a/core/vm/runtime/env.go
+++ b/core/vm/runtime/env.go
@@ -17,17 +17,15 @@
package runtime
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
)
func NewEnv(cfg *Config) *vm.EVM {
context := vm.Context{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
- GetHash: func(uint64) common.Hash { return common.Hash{} },
-
+ GetHash: cfg.GetHashFn,
Origin: cfg.Origin,
Coinbase: cfg.Coinbase,
BlockNumber: cfg.BlockNumber,
@@ -37,5 +35,5 @@ func NewEnv(cfg *Config) *vm.EVM {
GasPrice: cfg.GasPrice,
}
- return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
+ return vm.NewEVM(context, cfg.State, nil, cfg.ChainConfig, cfg.EVMConfig)
}
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 1e9ed7ae2d..63b2d6d9c2 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -17,16 +17,16 @@
package runtime
import (
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math"
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
// Config is a basic type specifying certain configuration flags for running
@@ -90,8 +90,8 @@ func setDefaults(cfg *Config) {
// Execute executes the code using the input as call data during the execution.
// It returns the EVM's return value, the new state and an error if it failed.
//
-// Executes sets up a in memory, temporarily, environment for the execution of
-// the given code. It makes sure that it's restored to it's original state afterwards.
+// Execute sets up an in-memory, temporary, environment for the execution of
+// the given code. It makes sure that it's restored to its original state afterwards.
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
if cfg == nil {
cfg = new(Config)
@@ -99,11 +99,11 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
setDefaults(cfg)
if cfg.State == nil {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db))
}
var (
- address = common.StringToAddress("contract")
+ address = common.BytesToAddress([]byte("contract"))
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
)
@@ -113,7 +113,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
// Call the code with the given configuration.
ret, _, err := vmenv.Call(
sender,
- common.StringToAddress("contract"),
+ common.BytesToAddress([]byte("contract")),
input,
cfg.GasLimit,
cfg.Value,
@@ -130,7 +130,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
setDefaults(cfg)
if cfg.State == nil {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db))
}
var (
diff --git a/core/vm/runtime/runtime_example_test.go b/core/vm/runtime/runtime_example_test.go
index b7d0ddc384..9bc1e78ef9 100644
--- a/core/vm/runtime/runtime_example_test.go
+++ b/core/vm/runtime/runtime_example_test.go
@@ -19,8 +19,8 @@ package runtime_test
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm/runtime"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/core/vm/runtime"
)
func ExampleExecute() {
diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go
index 2c4dc50265..89e6d4b0be 100644
--- a/core/vm/runtime/runtime_test.go
+++ b/core/vm/runtime/runtime_test.go
@@ -17,15 +17,19 @@
package runtime
import (
+ "github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"strings"
"testing"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/XinFinOrg/XDPoSChain/accounts/abi"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/consensus"
+ "github.com/XinFinOrg/XDPoSChain/core"
+ "github.com/XinFinOrg/XDPoSChain/core/state"
+ "github.com/XinFinOrg/XDPoSChain/core/types"
+ "github.com/XinFinOrg/XDPoSChain/core/vm"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
func TestDefaults(t *testing.T) {
@@ -94,7 +98,7 @@ func TestExecute(t *testing.T) {
}
func TestCall(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
+ db := rawdb.NewMemoryDatabase()
state, _ := state.New(common.Hash{}, state.NewDatabase(db))
address := common.HexToAddress("0x0a")
state.SetCode(address, []byte{
@@ -149,3 +153,204 @@ func BenchmarkCall(b *testing.B) {
}
}
}
+func benchmarkEVM_Create(bench *testing.B, code string) {
+ var (
+ db = rawdb.NewMemoryDatabase()
+ statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
+ sender = common.BytesToAddress([]byte("sender"))
+ receiver = common.BytesToAddress([]byte("receiver"))
+ )
+
+ statedb.CreateAccount(sender)
+ statedb.SetCode(receiver, common.FromHex(code))
+ runtimeConfig := Config{
+ Origin: sender,
+ State: statedb,
+ GasLimit: 10000000,
+ Difficulty: big.NewInt(0x200000),
+ Time: new(big.Int).SetUint64(0),
+ Coinbase: common.Address{},
+ BlockNumber: new(big.Int).SetUint64(1),
+ ChainConfig: ¶ms.ChainConfig{
+ ChainId: big.NewInt(1),
+ HomesteadBlock: new(big.Int),
+ ByzantiumBlock: new(big.Int),
+ ConstantinopleBlock: new(big.Int),
+ DAOForkBlock: new(big.Int),
+ DAOForkSupport: false,
+ EIP150Block: new(big.Int),
+ EIP155Block: new(big.Int),
+ EIP158Block: new(big.Int),
+ },
+ EVMConfig: vm.Config{},
+ }
+ // Warm up the intpools and stuff
+ bench.ResetTimer()
+ for i := 0; i < bench.N; i++ {
+ Call(receiver, []byte{}, &runtimeConfig)
+ }
+ bench.StopTimer()
+}
+
+func BenchmarkEVM_CREATE_500(bench *testing.B) {
+ // initcode size 500K, repeatedly calls CREATE and then modifies the mem contents
+ benchmarkEVM_Create(bench, "5b6207a120600080f0600152600056")
+}
+func BenchmarkEVM_CREATE2_500(bench *testing.B) {
+ // initcode size 500K, repeatedly calls CREATE2 and then modifies the mem contents
+ benchmarkEVM_Create(bench, "5b586207a120600080f5600152600056")
+}
+func BenchmarkEVM_CREATE_1200(bench *testing.B) {
+ // initcode size 1200K, repeatedly calls CREATE and then modifies the mem contents
+ benchmarkEVM_Create(bench, "5b62124f80600080f0600152600056")
+}
+func BenchmarkEVM_CREATE2_1200(bench *testing.B) {
+ // initcode size 1200K, repeatedly calls CREATE2 and then modifies the mem contents
+ benchmarkEVM_Create(bench, "5b5862124f80600080f5600152600056")
+}
+
+func fakeHeader(n uint64, parentHash common.Hash) *types.Header {
+ header := types.Header{
+ Coinbase: common.HexToAddress("0x00000000000000000000000000000000deadbeef"),
+ Number: big.NewInt(int64(n)),
+ ParentHash: parentHash,
+ Time: big.NewInt(1000),
+ Nonce: types.BlockNonce{0x1},
+ Extra: []byte{},
+ Difficulty: big.NewInt(0),
+ GasLimit: 100000,
+ }
+ return &header
+}
+
+type dummyChain struct {
+ counter int
+}
+
+func (d *dummyChain) CurrentHeader() *types.Header {
+ panic("implement me")
+}
+
+func (d *dummyChain) Config() *params.ChainConfig {
+ panic("implement me")
+}
+
+// Engine retrieves the chain's consensus engine.
+func (d *dummyChain) Engine() consensus.Engine {
+ return nil
+}
+
+// GetHeader returns the hash corresponding to their hash.
+func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header {
+ d.counter++
+ parentHash := common.Hash{}
+ s := common.LeftPadBytes(big.NewInt(int64(n-1)).Bytes(), 32)
+ copy(parentHash[:], s)
+
+ //parentHash := common.Hash{byte(n - 1)}
+ //fmt.Printf("GetHeader(%x, %d) => header with parent %x\n", h, n, parentHash)
+ return fakeHeader(n, parentHash)
+}
+
+// TestBlockhash tests the blockhash operation. It's a bit special, since it internally
+// requires access to a chain reader.
+func TestBlockhash(t *testing.T) {
+ // Current head
+ n := uint64(1000)
+ parentHash := common.Hash{}
+ s := common.LeftPadBytes(big.NewInt(int64(n-1)).Bytes(), 32)
+ copy(parentHash[:], s)
+ header := fakeHeader(n, parentHash)
+
+ // This is the contract we're using. It requests the blockhash for current num (should be all zeroes),
+ // then iteratively fetches all blockhashes back to n-260.
+ // It returns
+ // 1. the first (should be zero)
+ // 2. the second (should be the parent hash)
+ // 3. the last non-zero hash
+ // By making the chain reader return hashes which correlate to the number, we can
+ // verify that it obtained the right hashes where it should
+
+ /*
+
+ pragma solidity ^0.5.3;
+ contract Hasher{
+
+ function test() public view returns (bytes32, bytes32, bytes32){
+ uint256 x = block.number;
+ bytes32 first;
+ bytes32 last;
+ bytes32 zero;
+ zero = blockhash(x); // Should be zeroes
+ first = blockhash(x-1);
+ for(uint256 i = 2 ; i < 260; i++){
+ bytes32 hash = blockhash(x - i);
+ if (uint256(hash) != 0){
+ last = hash;
+ }
+ }
+ return (zero, first, last);
+ }
+ }
+
+ */
+ // The contract above
+ data := common.Hex2Bytes("6080604052348015600f57600080fd5b50600436106045576000357c010000000000000000000000000000000000000000000000000000000090048063f8a8fd6d14604a575b600080fd5b60506074565b60405180848152602001838152602001828152602001935050505060405180910390f35b600080600080439050600080600083409050600184034092506000600290505b61010481101560c35760008186034090506000816001900414151560b6578093505b5080806001019150506094565b508083839650965096505050505090919256fea165627a7a72305820462d71b510c1725ff35946c20b415b0d50b468ea157c8c77dff9466c9cb85f560029")
+ // The method call to 'test()'
+ input := common.Hex2Bytes("f8a8fd6d")
+ chain := &dummyChain{}
+ ret, _, err := Execute(data, input, &Config{
+ GetHashFn: core.GetHashFn(header, chain),
+ BlockNumber: new(big.Int).Set(header.Number),
+ })
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+ if len(ret) != 96 {
+ t.Fatalf("expected returndata to be 96 bytes, got %d", len(ret))
+ }
+
+ zero := new(big.Int).SetBytes(ret[0:32])
+ first := new(big.Int).SetBytes(ret[32:64])
+ last := new(big.Int).SetBytes(ret[64:96])
+ if zero.BitLen() != 0 {
+ t.Fatalf("expected zeroes, got %x", ret[0:32])
+ }
+ if first.Uint64() != 999 {
+ t.Fatalf("second block should be 999, got %d (%x)", first, ret[32:64])
+ }
+ if last.Uint64() != 744 {
+ t.Fatalf("last block should be 744, got %d (%x)", last, ret[64:96])
+ }
+ if exp, got := 255, chain.counter; exp != got {
+ t.Errorf("suboptimal; too much chain iteration, expected %d, got %d", exp, got)
+ }
+}
+
+// BenchmarkSimpleLoop test a pretty simple loop which loops
+// 1M (1 048 575) times.
+// Takes about 200 ms
+func BenchmarkSimpleLoop(b *testing.B) {
+ // 0xfffff = 1048575 loops
+ code := []byte{
+ byte(vm.PUSH3), 0x0f, 0xff, 0xff,
+ byte(vm.JUMPDEST), // [ count ]
+ byte(vm.PUSH1), 1, // [count, 1]
+ byte(vm.SWAP1), // [1, count]
+ byte(vm.SUB), // [ count -1 ]
+ byte(vm.DUP1), // [ count -1 , count-1]
+ byte(vm.PUSH1), 4, // [count-1, count -1, label]
+ byte(vm.JUMPI), // [ 0 ]
+ byte(vm.STOP),
+ }
+ //tracer := vm.NewJSONLogger(nil, os.Stdout)
+ //Execute(code, nil, &Config{
+ // EVMConfig: vm.Config{
+ // Debug: true,
+ // Tracer: tracer,
+ // }})
+
+ for i := 0; i < b.N; i++ {
+ Execute(code, nil, nil)
+ }
+}
diff --git a/core/vm/stack.go b/core/vm/stack.go
index 9c10d50ad1..c9c3d07f4b 100644
--- a/core/vm/stack.go
+++ b/core/vm/stack.go
@@ -21,7 +21,7 @@ import (
"math/big"
)
-// stack is an object for basic stack operations. Items popped to the stack are
+// Stack is an object for basic stack operations. Items popped to the stack are
// expected to be changed and modified. stack does not take care of adding newly
// initialised objects.
type Stack struct {
@@ -32,6 +32,7 @@ func newstack() *Stack {
return &Stack{data: make([]*big.Int, 0, 1024)}
}
+// Data returns the underlying big.Int array.
func (st *Stack) Data() []*big.Int {
return st.data
}
@@ -73,13 +74,7 @@ func (st *Stack) Back(n int) *big.Int {
return st.data[st.len()-n-1]
}
-func (st *Stack) require(n int) error {
- if st.len() < n {
- return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n)
- }
- return nil
-}
-
+// Print dumps the content of the stack
func (st *Stack) Print() {
fmt.Println("### stack ###")
if len(st.data) > 0 {
diff --git a/core/vm/stack_table.go b/core/vm/stack_table.go
index a4b1cfcd89..4a2da88879 100644
--- a/core/vm/stack_table.go
+++ b/core/vm/stack_table.go
@@ -17,28 +17,26 @@
package vm
import (
- "fmt"
-
- "github.com/ethereum/go-ethereum/params"
+ "github.com/XinFinOrg/XDPoSChain/params"
)
-func makeStackFunc(pop, push int) stackValidationFunc {
- return func(stack *Stack) error {
- if err := stack.require(pop); err != nil {
- return err
- }
-
- if stack.len()+push-pop > int(params.StackLimit) {
- return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit)
- }
- return nil
- }
+func minSwapStack(n int) int {
+ return minStack(n, n)
+}
+func maxSwapStack(n int) int {
+ return maxStack(n, n)
}
-func makeDupStackFunc(n int) stackValidationFunc {
- return makeStackFunc(n, n+1)
+func minDupStack(n int) int {
+ return minStack(n, n+1)
+}
+func maxDupStack(n int) int {
+ return maxStack(n, n+1)
}
-func makeSwapStackFunc(n int) stackValidationFunc {
- return makeStackFunc(n, n)
+func maxStack(pop, push int) int {
+ return int(params.StackLimit) + pop - push
+}
+func minStack(pops, push int) int {
+ return pops
}
diff --git a/core/vm/testdata/testcases_add.json b/core/vm/testdata/testcases_add.json
new file mode 100644
index 0000000000..c03ae96ada
--- /dev/null
+++ b/core/vm/testdata/testcases_add.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_and.json b/core/vm/testdata/testcases_and.json
new file mode 100644
index 0000000000..aba5f2463c
--- /dev/null
+++ b/core/vm/testdata/testcases_and.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_byte.json b/core/vm/testdata/testcases_byte.json
new file mode 100644
index 0000000000..88d7c7d807
--- /dev/null
+++ b/core/vm/testdata/testcases_byte.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_div.json b/core/vm/testdata/testcases_div.json
new file mode 100644
index 0000000000..b1f9c7fbac
--- /dev/null
+++ b/core/vm/testdata/testcases_div.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333332"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_eq.json b/core/vm/testdata/testcases_eq.json
new file mode 100644
index 0000000000..937eadb024
--- /dev/null
+++ b/core/vm/testdata/testcases_eq.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_exp.json b/core/vm/testdata/testcases_exp.json
new file mode 100644
index 0000000000..61818357f8
--- /dev/null
+++ b/core/vm/testdata/testcases_exp.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000c35"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3cb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"58cd20afa2f05a708ede54b48d3ae685db76b3bb83cf2cf95d4e8fb00bcbe61d"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"a732df505d0fa58f7121ab4b72c5197a24894c447c30d306a2b1704ff43419e3"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_gt.json b/core/vm/testdata/testcases_gt.json
new file mode 100644
index 0000000000..637bd3f6e6
--- /dev/null
+++ b/core/vm/testdata/testcases_gt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_lt.json b/core/vm/testdata/testcases_lt.json
new file mode 100644
index 0000000000..55252a4de2
--- /dev/null
+++ b/core/vm/testdata/testcases_lt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_mod.json b/core/vm/testdata/testcases_mod.json
new file mode 100644
index 0000000000..192503f26f
--- /dev/null
+++ b/core/vm/testdata/testcases_mod.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_mul.json b/core/vm/testdata/testcases_mul.json
new file mode 100644
index 0000000000..dc44c253f6
--- /dev/null
+++ b/core/vm/testdata/testcases_mul.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_or.json b/core/vm/testdata/testcases_or.json
new file mode 100644
index 0000000000..bfa561b585
--- /dev/null
+++ b/core/vm/testdata/testcases_or.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_sar.json b/core/vm/testdata/testcases_sar.json
new file mode 100644
index 0000000000..c93abbd654
--- /dev/null
+++ b/core/vm/testdata/testcases_sar.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_sdiv.json b/core/vm/testdata/testcases_sdiv.json
new file mode 100644
index 0000000000..18cb666ab5
--- /dev/null
+++ b/core/vm/testdata/testcases_sdiv.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_sgt.json b/core/vm/testdata/testcases_sgt.json
new file mode 100644
index 0000000000..aa581a6549
--- /dev/null
+++ b/core/vm/testdata/testcases_sgt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_shl.json b/core/vm/testdata/testcases_shl.json
new file mode 100644
index 0000000000..65e9c07b77
--- /dev/null
+++ b/core/vm/testdata/testcases_shl.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000a0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_shr.json b/core/vm/testdata/testcases_shr.json
new file mode 100644
index 0000000000..a38491350d
--- /dev/null
+++ b/core/vm/testdata/testcases_shr.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_signext.json b/core/vm/testdata/testcases_signext.json
new file mode 100644
index 0000000000..bdadd400e7
--- /dev/null
+++ b/core/vm/testdata/testcases_signext.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_slt.json b/core/vm/testdata/testcases_slt.json
new file mode 100644
index 0000000000..4369b96fd8
--- /dev/null
+++ b/core/vm/testdata/testcases_slt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_smod.json b/core/vm/testdata/testcases_smod.json
new file mode 100644
index 0000000000..980e0341a7
--- /dev/null
+++ b/core/vm/testdata/testcases_smod.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_sub.json b/core/vm/testdata/testcases_sub.json
new file mode 100644
index 0000000000..b3881a5ab6
--- /dev/null
+++ b/core/vm/testdata/testcases_sub.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000007"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/core/vm/testdata/testcases_xor.json b/core/vm/testdata/testcases_xor.json
new file mode 100644
index 0000000000..4cc2dddd7d
--- /dev/null
+++ b/core/vm/testdata/testcases_xor.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/coverage.txt b/coverage.txt
new file mode 100644
index 0000000000..95096dcc81
--- /dev/null
+++ b/coverage.txt
@@ -0,0 +1,4253 @@
+mode: atomic
+github.com/XinFinOrg/XDPoSChain/accounts/errors.go:59.46,63.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/errors.go:66.44,68.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:67.63,72.9 3 29
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:86.2,86.26 1 27
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:89.2,89.39 1 26
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:116.2,116.20 1 23
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:73.28,74.50 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:76.46,77.116 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:79.47,80.30 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:82.10,83.56 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:86.26,88.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:89.39,95.40 3 65
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:100.3,101.10 2 65
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:104.3,105.66 2 64
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:111.3,114.33 2 62
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:95.40,98.4 2 37
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:101.10,103.4 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:105.66,106.18 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:109.4,109.93 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:106.18,108.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:121.44,123.33 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:134.2,134.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:123.33,125.30 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:129.3,130.15 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:125.30,128.4 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/hd.go:130.15,132.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:43.47,46.35 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:50.2,53.35 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:57.2,64.35 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:68.2,70.11 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:46.35,48.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:53.35,55.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:64.35,67.3 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:74.34,78.2 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:82.29,84.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:94.2,94.6 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:84.15,86.35 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:89.3,90.19 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:86.35,88.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:94.6,95.10 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:96.30,99.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:105.4,108.23 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:110.26,113.10 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:100.23,101.49 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:102.23,103.48 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:119.58,121.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:124.39,131.2 5 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:134.55,139.16 4 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:142.2,142.38 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:147.2,147.30 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:139.16,141.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:142.38,143.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:143.29,145.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:153.58,157.36 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:162.2,162.31 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:157.36,158.31 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:158.31,160.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:167.74,169.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:175.56,176.33 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:184.2,184.14 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:176.33,177.49 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:178.3,178.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:182.3,182.71 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:177.49,177.97 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:178.22,180.12 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:189.55,190.33 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:198.2,198.14 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:190.33,191.49 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:192.3,192.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:196.3,196.44 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:191.49,191.97 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/manager.go:192.22,194.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:44.40,46.39 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:49.2,52.8 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:46.39,48.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:56.30,57.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:60.2,60.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:57.20,59.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:64.38,66.19 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:69.2,69.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:66.19,68.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:73.44,75.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:83.31,84.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:87.2,87.46 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/url.go:84.28,86.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:48.35,51.38 3 225
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:55.2,55.69 1 225
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:51.38,54.3 2 348
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:58.38,60.38 2 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:63.2,64.40 2 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:70.2,71.18 2 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:74.2,74.133 1 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:60.38,62.3 1 60
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:64.40,65.27 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:68.3,68.37 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:65.27,67.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:71.18,73.3 1 12
+github.com/XinFinOrg/XDPoSChain/accounts/abi/method.go:77.34,79.2 1 223
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:29.49,32.2 2 33
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:36.61,37.13 1 148
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:38.21,39.31 1 87
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:40.16,41.75 1 13
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:42.17,43.43 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:47.3,47.55 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:48.14,49.26 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:52.3,52.46 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:53.15,54.43 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:57.3,57.66 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:58.32,59.43 1 36
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:62.3,62.56 1 36
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:63.10,64.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:43.43,45.4 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:49.26,51.4 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:54.43,56.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:59.43,61.4 1 36
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:69.42,70.36 1 161
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:71.83,72.52 1 53
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:73.78,74.39 1 78
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:75.19,76.44 1 30
+github.com/XinFinOrg/XDPoSChain/accounts/abi/pack.go:77.10,78.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:26.46,27.62 1 195
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:30.2,30.10 1 194
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:27.62,29.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:35.82,36.14 1 298
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:58.2,58.27 1 142
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:37.9,38.15 1 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:41.3,41.30 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:42.10,43.15 1 32
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:46.3,46.32 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:47.10,48.15 1 50
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:51.3,51.32 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:52.10,53.15 1 34
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:56.3,56.32 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:38.15,40.4 1 32
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:43.15,45.4 1 24
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:48.15,50.4 1 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:53.15,55.4 1 26
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:63.62,67.2 3 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:73.57,76.9 3 107
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:86.2,86.12 1 79
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:77.37,78.15 1 79
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:79.43,80.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:81.37,82.38 1 19
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:83.10,84.81 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:90.54,91.66 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:94.2,94.12 1 19
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:91.66,93.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:99.24,101.11 1 29
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:111.2,111.12 1 26
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:102.22,102.22 0 15
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:103.36,104.58 1 13
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:108.10,109.62 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:104.58,107.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:115.58,117.27 2 16
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:127.2,127.12 1 12
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:117.27,119.18 2 35
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:122.3,122.20 1 34
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:125.3,125.23 1 31
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:119.18,121.4 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/reflect.go:122.20,124.4 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:36.42,40.41 3 75
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:44.2,44.17 1 75
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:40.41,42.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:52.71,54.16 1 27
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:63.2,64.12 2 27
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:68.2,69.16 2 25
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:73.2,73.47 1 23
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:54.16,57.17 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:60.3,60.24 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:57.17,59.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:64.12,66.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:69.16,71.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:77.78,78.22 1 83
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:83.2,83.41 1 82
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:91.2,91.66 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:78.22,80.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:83.41,84.26 1 68
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:87.3,87.42 1 68
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:84.26,86.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:88.8,88.46 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:88.46,90.3 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:95.50,105.54 2 75
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:109.2,111.31 3 75
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:134.2,134.12 1 75
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:105.54,107.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:111.31,112.21 1 193
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:113.22,116.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:118.23,124.5 1 182
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:125.16,130.5 1 11
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:139.61,140.37 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:145.2,145.63 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:140.37,141.44 1 175
+github.com/XinFinOrg/XDPoSChain/accounts/abi/abi.go:141.44,143.4 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:31.65,32.21 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:35.2,35.47 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:32.21,34.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:40.54,41.64 1 76
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:45.2,45.43 1 76
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:49.2,49.25 1 73
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:57.2,57.67 1 59
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:60.2,60.12 1 57
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:41.64,43.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:45.43,47.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:49.25,50.20 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:50.20,52.4 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:53.8,53.32 1 68
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:53.32,55.3 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:57.67,59.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:65.51,66.38 1 331
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:71.2,71.28 1 269
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:66.38,68.3 1 62
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:71.28,73.3 1 13
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:73.8,73.57 1 256
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:73.57,75.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:75.8,77.3 1 253
+github.com/XinFinOrg/XDPoSChain/accounts/abi/error.go:82.47,84.2 1 21
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:36.36,38.37 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:44.2,44.76 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:38.37,40.20 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:40.20,42.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:49.33,52.33 3 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:56.2,56.110 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/event.go:52.33,55.3 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/numbers.go:48.30,50.2 1 163
+github.com/XinFinOrg/XDPoSChain/accounts/abi/numbers.go:53.37,54.18 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/numbers.go:58.2,58.14 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/numbers.go:55.95,56.14 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:61.46,63.52 1 723
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:67.2,71.32 2 723
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:106.2,109.28 3 517
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:123.2,123.43 1 515
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:165.2,165.8 1 515
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:63.52,65.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:71.32,75.17 3 206
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:79.3,84.21 4 206
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:103.3,103.18 1 206
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:75.17,77.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:84.21,90.4 4 106
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:90.9,90.28 1 100
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:90.28,96.18 5 100
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:99.4,99.59 1 100
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:96.18,98.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:100.9,102.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:109.28,112.17 3 385
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:112.17,114.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:115.8,116.56 1 132
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:116.56,120.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:124.13,127.16 3 81
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:128.14,131.17 3 217
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:132.14,135.41 3 21
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:136.17,140.20 4 60
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:141.16,144.19 3 28
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:145.15,146.19 1 105
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:156.18,160.58 4 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:161.10,162.59 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:146.19,150.4 3 18
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:150.9,155.4 4 87
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:169.37,171.2 1 411
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:173.53,177.40 2 194
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:181.2,181.38 1 193
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:197.2,197.31 1 148
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:177.40,179.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:181.38,184.32 2 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:191.3,191.21 1 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:184.32,186.18 2 99
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:189.4,189.35 1 99
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:186.18,188.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:191.21,193.4 1 18
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:193.9,193.28 1 27
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:193.28,195.4 1 27
+github.com/XinFinOrg/XDPoSChain/accounts/abi/type.go:202.43,204.2 1 307
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:29.59,30.14 1 149
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:31.21,32.21 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:33.22,34.47 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:35.22,36.47 1 30
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:37.22,38.47 1 33
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:39.20,40.27 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:41.21,42.54 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:43.21,44.54 1 6
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:45.21,46.54 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:47.10,48.34 1 44
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:53.42,54.30 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:59.2,59.18 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:54.30,55.13 1 62
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:55.13,57.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:60.9,61.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:62.9,63.19 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:64.10,65.27 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:71.73,72.23 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:75.2,75.67 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:80.2,80.8 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:72.23,74.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:75.67,77.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:77.8,79.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:84.63,85.25 1 12
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:89.2,92.31 3 12
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:85.25,87.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:96.38,100.24 2 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:104.2,104.13 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:100.24,103.3 2 13
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:108.81,109.14 1 68
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:112.2,112.33 1 68
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:117.2,119.20 2 67
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:131.2,132.20 2 67
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:136.2,136.57 1 67
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:148.2,148.34 1 67
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:109.14,111.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:112.33,114.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:119.20,122.3 1 19
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:122.8,122.27 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:122.27,125.3 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:125.8,127.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:132.20,134.3 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:136.57,139.17 2 149
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:144.3,144.48 1 149
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:139.17,141.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:153.70,154.28 1 271
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:158.2,165.30 2 271
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:174.2,174.13 1 263
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:154.28,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:165.30,167.17 2 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:167.17,169.4 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:170.8,172.3 1 226
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:175.15,176.46 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:177.15,178.49 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:179.16,180.48 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:181.21,182.48 1 149
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:183.14,184.32 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:185.17,186.50 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:187.14,188.47 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:189.15,190.40 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:191.20,192.41 1 12
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:193.18,194.43 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:195.10,196.54 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:201.88,206.40 4 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:210.2,210.32 1 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:214.2,220.29 6 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:224.2,224.37 1 38
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:227.2,229.8 3 37
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:206.40,208.3 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:210.32,212.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:220.29,222.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/unpack.go:224.37,226.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:37.60,44.16 3 263
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:48.2,49.16 2 263
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:52.2,55.12 3 263
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:44.16,46.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:49.16,51.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:60.51,62.32 2 102
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:67.2,67.12 1 102
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:62.32,63.19 1 159
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:63.19,65.4 1 151
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:71.51,73.32 2 161
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:78.2,78.12 1 161
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:73.32,74.19 1 230
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:74.19,76.4 1 218
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:82.43,84.2 1 80
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:87.69,90.46 1 82
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:93.2,94.16 2 82
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:97.2,97.25 1 80
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:100.2,100.52 1 51
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:90.46,92.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:94.16,96.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:97.25,99.3 1 29
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:103.93,111.71 2 29
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:115.2,115.28 1 26
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:120.2,120.45 1 22
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:146.2,146.12 1 18
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:111.71,113.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:115.28,116.66 1 15
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:116.66,118.4 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:120.45,124.15 2 40
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:125.23,127.18 2 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:130.37,131.23 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:134.4,135.61 2 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:139.4,139.59 1 19
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:142.11,143.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:127.18,129.5 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:131.23,133.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:135.61,137.5 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:139.59,141.5 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:150.94,151.32 1 51
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:154.2,158.28 4 51
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:167.2,167.59 1 50
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:151.32,153.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:158.28,160.66 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:164.3,164.56 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:160.66,162.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:173.34,177.23 3 17
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:183.2,183.13 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:177.23,181.3 2 5
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:189.77,192.49 3 89
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:212.2,212.20 1 80
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:192.49,194.28 2 122
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:207.3,207.17 1 122
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:210.3,210.43 1 113
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:194.28,206.4 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:207.17,209.4 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:217.75,219.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:222.70,225.31 2 25
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:230.2,234.33 3 24
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:241.2,242.25 2 24
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:264.2,266.17 2 23
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:225.31,227.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:234.33,235.31 1 37
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:235.31,237.4 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:237.9,239.4 1 27
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:242.25,246.17 3 37
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:250.3,250.40 1 36
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:246.17,248.4 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:250.40,258.4 3 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:258.9,261.4 1 16
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:271.38,272.40 1 56
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:275.2,275.21 1 56
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:278.2,278.47 1 55
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:272.40,274.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:275.21,277.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:282.74,285.38 3 21
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:293.2,293.12 1 20
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:285.38,287.32 1 45
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:287.32,288.65 1 19
+github.com/XinFinOrg/XDPoSChain/accounts/abi/argument.go:288.65,290.5 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:88.156,96.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:100.179,105.16 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:108.2,109.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:112.2,113.30 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:105.16,107.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:109.16,111.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:120.110,122.17 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:126.2,127.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:130.2,136.18 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:161.2,161.16 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:164.2,164.45 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:122.17,124.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:127.16,129.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:136.18,138.10 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:141.3,142.37 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:138.10,140.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:142.37,144.64 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:144.64,146.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:146.10,146.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:146.29,148.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:150.8,152.37 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:152.37,154.68 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:154.68,156.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:156.10,156.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:156.29,158.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:161.16,163.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:168.120,171.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:174.2,174.44 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:171.16,173.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:179.82,181.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:185.122,190.18 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:193.2,194.23 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:203.2,204.21 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:210.2,211.19 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:228.2,229.21 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:234.2,234.24 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:237.2,238.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:241.2,241.92 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:244.2,244.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:190.18,192.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:194.23,196.17 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:196.17,198.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:199.8,201.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:204.21,206.17 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:206.17,208.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:211.19,213.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:221.3,223.17 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:213.22,214.99 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:214.99,216.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:216.10,216.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:216.29,218.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:223.17,225.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:229.21,231.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:231.8,233.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:234.24,236.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:238.16,240.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:241.92,243.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:249.135,251.17 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:255.2,258.16 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:262.2,269.21 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:275.2,276.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:279.2,279.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:290.2,290.16 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:293.2,293.23 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:251.17,253.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:258.16,260.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:269.21,271.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:276.16,278.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:279.69,280.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:287.3,287.13 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:280.28,281.11 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:282.21,282.21 0 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:283.16,284.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:290.16,292.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:298.133,300.17 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:304.2,307.16 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:311.2,317.23 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:320.2,321.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:324.2,324.23 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:300.17,302.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:307.16,309.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:317.23,319.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:321.16,323.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:328.87,329.23 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:334.2,335.49 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:340.2,340.50 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:329.23,330.60 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:330.60,332.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:335.49,336.18 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:336.18,338.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:345.57,346.16 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:349.2,349.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/base.go:346.16,348.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:48.101,52.34 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:131.2,145.51 5 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:149.2,149.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:157.2,157.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:52.34,55.17 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:59.3,59.48 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:67.3,72.43 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:98.3,98.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:120.3,128.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:55.17,57.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:59.48,60.26 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:63.4,63.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:60.26,62.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:72.43,79.44 5 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:84.4,86.46 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:92.4,92.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:79.44,80.25 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:80.25,82.6 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:86.46,87.26 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:87.26,89.6 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:92.22,94.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:94.10,96.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:98.42,100.26 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:104.4,109.44 5 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:118.4,118.82 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:100.26,101.13 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:109.44,111.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:111.22,112.26 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:112.26,114.7 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:145.51,147.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:149.20,151.17 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:154.3,154.27 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:151.17,153.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:175.89,180.32 4 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:184.2,184.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:180.32,183.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:189.63,192.44 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:195.2,196.12 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:192.44,194.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:202.39,206.2 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:211.58,213.9 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:214.48,215.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:217.46,219.58 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:221.85,223.19 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:227.3,227.35 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:229.45,230.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:232.47,233.33 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:235.10,236.37 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:224.30,225.68 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:242.65,245.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:250.41,254.2 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:259.60,261.9 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:262.48,264.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:267.3,267.21 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:270.3,270.36 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:272.46,274.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:277.3,277.33 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:279.85,283.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:287.3,295.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:298.3,298.34 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:300.45,301.32 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:303.47,304.33 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:306.10,307.37 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:264.22,266.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:267.21,269.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:274.22,276.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:283.22,285.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:295.22,297.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:320.44,322.44 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:325.2,325.14 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:322.44,324.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:330.46,332.43 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:335.2,335.14 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:332.43,334.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:341.42,341.77 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:347.62,348.18 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:349.16,350.18 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:351.18,352.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:353.16,354.18 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:355.18,356.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:357.17,358.16 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:359.19,360.17 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:361.18,362.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:363.10,365.22 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:368.3,368.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:365.22,367.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:369.30,370.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:373.4,373.66 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:375.11,376.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:370.22,372.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:389.38,390.40 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:393.2,393.21 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:396.2,396.60 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:390.40,392.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:393.21,395.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:400.40,401.40 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:404.2,404.21 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:407.2,407.60 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:401.40,403.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:404.21,406.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:411.39,415.26 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:431.2,431.15 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:415.26,416.10 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:417.15,418.46 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:420.16,422.19 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:424.17,425.18 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:427.11,428.23 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:436.42,437.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:440.2,441.27 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:454.2,454.13 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:437.19,439.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:441.27,443.21 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:448.3,449.35 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:452.3,452.23 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:443.21,445.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/bind.go:449.35,451.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:31.66,33.31 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:96.2,96.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:33.31,34.31 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:34.31,38.31 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:93.4,93.40 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:39.21,40.28 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:41.24,42.66 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:43.18,45.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:46.14,47.13 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:50.14,52.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:53.15,55.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:56.15,58.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:59.15,61.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:62.15,64.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:65.16,67.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:68.16,70.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:71.16,73.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:74.16,76.28 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:77.16,79.28 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:81.12,85.12 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:47.13,49.6 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:86.93,87.77 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:89.13,90.66 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:110.85,112.32 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:116.2,116.29 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:188.2,188.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:112.32,114.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:116.29,117.19 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:120.3,123.23 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:186.3,186.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:117.19,119.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:124.21,125.43 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:128.21,130.49 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:132.22,134.50 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:136.22,138.50 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:140.22,142.43 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:144.22,146.51 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:148.23,150.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:152.23,154.52 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:156.23,158.44 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:160.11,162.24 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:125.43,127.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:163.21,164.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:166.24,169.37 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:171.23,173.36 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:175.12,177.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:178.41,179.87 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/topics.go:181.13,182.65 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:31.101,36.6 4 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:36.6,38.21 2 4
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:41.3,41.17 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:47.3,47.10 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:38.21,40.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:41.17,43.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:43.9,45.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:48.21,49.25 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:50.24,50.24 0 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:57.104,58.20 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:61.2,62.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:65.2,65.51 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:71.2,72.34 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:75.2,75.37 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:58.20,60.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:62.16,64.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:65.51,67.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/util.go:72.34,74.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:33.79,35.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:38.2,39.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:42.2,42.48 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:35.16,37.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:39.16,41.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:47.62,51.112 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:51.112,52.26 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:55.4,56.18 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:59.4,59.46 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:52.26,54.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/auth.go:56.18,58.5 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:43.44,43.61 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:44.44,44.81 1 4858
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:45.44,45.71 1 1644
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:54.47,56.32 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:62.2,62.63 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:56.32,58.29 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:58.29,60.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:77.68,86.2 3 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:88.55,95.2 6 1067
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:97.62,102.2 4 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:104.58,108.49 3 811
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:109.2,109.48 1 811
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:113.2,116.83 4 809
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:108.49,108.98 1 5570
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:109.48,111.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:120.58,125.76 4 248
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:125.76,127.3 1 248
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:127.8,129.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:133.51,136.49 3 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:138.2,138.51 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:136.49,136.86 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:138.51,141.77 3 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:141.77,143.4 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:143.9,145.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:149.88,150.23 1 499
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:155.2,155.14 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:150.23,151.23 1 28539
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:151.23,153.4 1 497
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:161.76,164.37 2 261
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:167.2,167.22 1 261
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:181.2,181.22 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:164.37,166.3 1 257
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:167.22,169.60 1 258
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:172.3,172.26 1 258
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:177.3,177.38 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:169.60,171.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:172.26,173.31 1 263
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:173.31,175.5 1 255
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:177.38,179.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:182.9,183.25 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:184.9,185.40 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:186.10,190.33 4 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:194.39,197.24 2 1332
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:201.2,201.24 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:212.2,215.19 4 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:197.24,200.3 2 1315
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:201.24,203.3 1 12
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:203.8,204.10 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:205.24,205.24 0 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:206.11,208.10 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:218.33,221.24 3 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:224.2,224.22 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:228.2,228.16 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:221.24,223.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:224.22,227.3 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:233.46,236.16 2 27
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:240.2,240.92 1 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:244.2,250.53 2 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:273.2,275.38 2 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:280.2,280.38 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:283.2,283.38 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:290.2,292.9 2 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:296.2,297.12 2 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:236.16,239.3 2 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:240.92,242.3 1 9
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:250.53,252.17 2 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:256.3,262.10 6 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:270.3,270.13 1 6
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:252.17,255.4 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:263.19,264.72 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:265.35,266.94 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:267.11,268.98 1 10
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:275.38,276.45 1 13
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:276.45,278.4 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:280.38,282.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:283.38,286.39 3 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:286.39,288.4 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:293.31,293.31 0 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/account_cache.go:294.10,294.10 0 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:94.51,103.2 3 785
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:105.51,108.16 3 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:112.2,116.16 5 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:119.2,120.16 2 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:124.2,127.12 3 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:108.16,110.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:116.16,118.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:120.16,122.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:130.62,138.2 3 1329
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:143.47,146.16 3 538
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:149.2,151.16 3 538
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:154.2,155.51 2 538
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:158.2,158.12 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:146.16,147.77 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:151.16,152.68 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:155.51,157.3 1 537
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:161.43,163.16 2 791
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:166.2,166.46 1 791
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:163.16,165.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:169.92,171.16 2 791
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:174.2,175.59 2 791
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:179.2,179.20 1 791
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:171.16,173.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:175.59,178.3 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:182.54,186.65 2 793
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:191.2,192.16 2 793
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:195.2,195.44 1 793
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:200.2,201.34 2 793
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:186.65,188.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:192.16,194.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:195.44,199.3 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:206.49,209.2 2 792
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:211.36,214.19 3 792
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:219.2,219.144 1 792
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:214.19,216.3 1 792
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/key.go:216.8,218.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:79.65,84.2 4 6
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:88.52,93.2 4 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:95.41,107.45 5 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:111.2,113.33 3 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:107.45,109.3 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:113.33,115.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:120.49,130.2 6 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:134.38,143.31 5 1035
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:165.2,165.36 1 1035
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:168.2,172.31 3 1035
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:143.31,145.71 1 269168
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:150.3,150.71 1 269168
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:158.3,158.45 1 268380
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:145.71,148.4 2 241
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:150.71,155.12 4 788
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:158.45,161.12 3 268380
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:165.36,167.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:172.31,174.3 1 1031
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:179.84,188.18 4 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:192.2,192.12 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:188.18,191.3 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:200.31,201.6 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:201.6,203.10 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:208.3,212.34 3 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:217.3,217.17 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:204.21,204.21 0 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:205.41,205.41 0 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:212.34,216.4 3 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:222.58,224.2 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:227.51,229.2 1 18
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:233.73,238.16 2 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:241.2,241.16 1 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:247.2,248.16 2 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:252.2,252.12 1 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:238.16,240.3 1 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:241.16,243.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:248.16,251.3 2 243
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:257.79,263.12 4 21
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:267.2,267.50 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:263.12,265.3 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:271.117,277.12 4 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:281.2,281.20 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:284.2,284.74 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:277.12,279.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:281.20,283.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:290.126,292.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:295.2,296.42 2 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:292.16,294.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:301.150,303.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:306.2,309.20 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:312.2,312.66 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:303.16,305.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:309.20,311.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:316.73,318.2 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:321.53,323.44 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:329.2,329.12 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:323.44,326.3 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:326.8,328.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:339.101,341.16 2 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:345.2,348.11 4 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:358.2,358.17 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:364.2,365.12 2 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:341.16,343.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:348.11,349.21 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:356.3,356.17 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:349.21,354.4 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:358.17,361.3 2 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:361.8,363.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:369.72,375.2 5 251
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:377.102,379.16 2 251
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:382.2,383.20 2 251
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:379.16,381.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:386.85,389.9 3 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:390.17,390.17 0 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:392.13,398.29 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:402.3,402.17 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:398.29,401.4 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:408.77,410.16 2 788
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:415.2,417.21 3 788
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:410.16,412.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:421.110,423.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:426.2,427.55 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:432.2,432.45 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:423.16,425.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:427.55,429.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:429.8,431.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:436.104,438.41 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:441.2,441.16 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:444.2,444.41 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:438.41,440.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:441.16,443.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:448.102,450.38 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:453.2,453.38 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:450.38,452.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:456.86,458.73 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:461.2,463.15 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:458.73,460.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:467.88,469.16 2 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:472.2,472.60 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:469.16,471.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:477.99,479.16 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:482.2,484.15 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:479.16,481.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:488.35,490.19 2 247
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore.go:490.19,492.3 1 988
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:35.107,37.16 2 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:40.2,43.20 4 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:37.16,39.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:46.83,54.16 3 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:57.2,58.16 2 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:61.2,61.28 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:64.2,76.16 6 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:79.2,89.33 6 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:92.2,92.17 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:54.16,56.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:58.16,60.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:61.28,63.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:76.16,78.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:89.33,91.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:95.56,98.16 2 28
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:101.2,104.21 4 28
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:98.16,100.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:107.64,109.16 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:112.2,116.22 5 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:119.2,119.23 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:109.16,111.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:116.22,118.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:123.35,124.18 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:128.2,129.55 2 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:135.2,135.56 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:140.2,140.34 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:124.18,126.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:129.55,131.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:131.8,131.25 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:131.25,133.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:135.56,136.23 1 48
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/presale.go:136.23,138.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:36.44,42.2 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:47.27,48.29 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:51.2,52.13 2 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:48.29,50.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:55.27,57.2 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:59.26,60.15 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:66.2,68.68 2 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:72.2,89.22 8 12
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:92.2,93.6 2 12
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:60.15,65.3 4 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:68.68,71.3 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:89.22,91.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:93.6,94.10 1 3995
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:95.17,96.10 1 3
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:97.15,99.24 1 3970
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:103.21,105.27 2 13
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/watch.go:99.24,102.5 2 15
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:40.86,45.16 3 27
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:48.2,58.27 7 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:76.2,88.39 8 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:45.16,47.3 1 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:58.27,61.22 2 18
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:66.3,69.33 3 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:72.3,72.33 1 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:61.22,63.12 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:69.33,71.4 1 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:72.33,74.4 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:92.39,94.76 1 18
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:98.2,98.46 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:101.2,101.14 1 16
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:94.76,96.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/file_cache.go:98.46,100.3 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:77.95,80.16 2 9
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:83.2,84.16 2 9
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:88.2,88.25 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:91.2,91.17 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:80.16,82.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:84.16,86.3 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:88.25,90.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:95.79,98.2 2 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:100.85,102.16 2 8
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:105.2,105.40 1 8
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:102.16,104.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:108.63,109.30 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:109.30,111.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:111.8,113.3 1 7
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:118.78,122.16 4 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:125.2,130.16 5 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:133.2,160.41 11 11
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:122.16,124.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:130.16,132.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:164.60,167.52 2 15
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:171.2,175.64 2 15
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:189.2,189.16 1 15
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:192.2,198.8 2 10
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:167.52,169.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:175.64,177.52 2 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:180.3,180.47 1 1
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:177.52,179.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:181.8,183.52 2 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:186.3,186.47 1 14
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:183.52,185.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:189.16,191.3 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:201.109,202.37 1 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:206.2,206.49 1 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:210.2,212.16 3 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:216.2,217.16 2 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:221.2,222.16 2 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:226.2,227.16 2 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:231.2,232.38 2 22
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:236.2,237.16 2 17
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:240.2,240.30 1 17
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:202.37,204.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:206.49,208.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:212.16,214.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:217.16,219.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:222.16,224.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:227.16,229.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:232.38,234.3 1 5
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:237.16,239.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:243.109,246.16 3 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:250.2,251.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:255.2,256.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:260.2,261.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:265.2,266.38 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:270.2,271.16 2 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:274.2,274.30 1 2
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:246.16,248.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:251.16,253.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:256.16,258.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:261.16,263.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:266.38,268.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:271.16,273.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:277.68,280.16 3 24
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:283.2,285.36 2 24
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:301.2,301.63 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:280.16,282.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:285.36,291.3 4 20
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:291.8,291.39 1 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:291.39,294.27 3 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:297.3,298.18 2 4
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:294.27,296.4 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:307.35,309.9 2 88
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:312.2,312.12 1 88
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_passphrase.go:309.9,311.3 1 88
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:32.90,34.16 2 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:37.2,39.56 3 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:42.2,42.25 1 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:45.2,45.17 1 246
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:34.16,36.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:39.56,41.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:42.25,44.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:48.80,50.16 2 785
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:53.2,53.40 1 785
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:50.16,52.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:56.58,57.30 1 785
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:57.30,59.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_plain.go:59.8,61.3 1 785
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:35.45,37.2 1 537001
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:41.51,45.57 3 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:48.2,48.22 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:45.57,47.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:53.56,53.70 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:57.40,57.54 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:61.56,63.2 1 269944
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:67.66,69.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:73.99,75.2 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:79.101,79.102 0 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:85.90,87.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:90.2,90.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:94.2,94.43 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:87.42,89.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:90.69,92.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:101.128,103.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:106.2,106.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:110.2,110.48 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:103.42,105.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:106.69,108.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:115.123,117.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:120.2,120.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:124.2,124.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:117.42,119.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:120.69,122.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:129.161,131.42 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:134.2,134.69 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:138.2,138.74 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:131.42,133.3 1 0
+github.com/XinFinOrg/XDPoSChain/accounts/keystore/keystore_wallet.go:134.69,136.3 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:90.31,99.2 1 9238
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:116.52,124.2 1 694106
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:142.75,150.2 1 8439
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:153.36,156.22 3 8439
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:156.22,159.3 2 8446
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:164.39,168.33 4 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:171.2,171.9 1 8948
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:177.2,177.10 1 8948
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:168.33,170.3 1 1288
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:172.20,172.20 0 502
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:173.10,175.15 2 8446
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:183.40,185.2 1 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:196.51,199.32 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:206.2,208.32 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:221.2,225.40 5 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:242.2,244.40 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:199.32,201.15 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:204.3,204.61 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:201.15,203.4 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:208.32,211.25 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:217.3,219.14 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:211.25,213.35 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:213.35,215.5 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:225.40,228.26 3 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:231.3,231.22 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:234.3,235.25 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:238.3,239.27 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:228.26,230.4 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:231.22,233.4 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:235.25,237.4 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:253.70,260.44 6 8446
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:272.2,274.3 1 8446
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:260.44,262.35 2 41612
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:267.3,269.13 3 41612
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:262.35,266.4 3 685660
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:280.32,282.2 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:285.37,287.2 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:292.46,299.63 5 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:304.2,310.29 5 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:313.2,317.21 5 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:299.63,301.3 1 4739
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:301.8,303.3 1 5497
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:310.29,312.3 1 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:324.35,326.2 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:333.50,335.12 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:338.2,343.17 6 10226
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:346.2,346.14 1 10226
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:350.2,351.17 2 10226
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:354.2,357.30 3 10226
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:368.2,371.15 3 10226
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:335.12,337.3 1 10
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:343.17,345.3 1 10193
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:346.14,348.3 1 10206
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:351.17,353.3 1 628
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:357.30,361.15 3 227422
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:364.3,366.6 3 227422
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:361.15,363.4 1 9427
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:379.64,383.6 4 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:402.2,402.25 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:383.6,387.40 4 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:394.3,394.17 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:397.3,398.17 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:387.40,389.24 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:392.4,392.9 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:389.24,391.5 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:394.17,395.9 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:398.17,399.9 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:406.29,409.2 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:416.47,420.2 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:424.35,425.21 1 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:437.2,438.20 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:425.21,427.32 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:433.3,434.17 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:427.32,429.23 2 62588
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:429.23,431.5 1 52352
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:441.58,445.43 3 237658
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:459.2,459.30 1 5222
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:445.43,446.13 1 232436
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:457.3,457.9 1 232436
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:446.13,451.14 4 232436
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:455.4,455.40 1 232161
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:451.14,454.5 2 275
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:462.71,464.6 2 237383
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:464.6,465.13 1 476601
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:470.3,470.34 1 476601
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:473.3,473.51 1 249179
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:483.3,484.13 2 249179
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:489.3,491.6 3 239218
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:465.13,467.4 1 249179
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:467.9,469.4 1 227422
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:470.34,472.4 1 227422
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:473.51,479.4 4 227798
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:479.9,481.4 1 21381
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:484.13,487.4 2 9961
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:496.37,497.21 1 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:500.2,502.10 3 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:497.21,499.3 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:508.33,510.2 1 454844
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:512.31,514.13 2 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:517.2,517.35 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:514.13,516.3 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:520.27,521.38 1 59296
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:524.2,524.10 1 59296
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:521.38,523.3 1 310064
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:529.54,531.6 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:531.6,538.16 3 48094
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:542.3,544.6 3 37858
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:538.16,541.4 2 10236
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:554.33,556.2 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt.go:559.31,561.2 1 0
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:39.60,44.26 5 10493
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:46.2,46.11 1 10493
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:49.2,54.3 1 10493
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:44.27,45.3 0 53894
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:46.11,48.3 1 10393
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:59.44,60.21 1 10493
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:64.2,64.28 1 10493
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:60.21,62.3 1 10
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:67.51,71.20 4 461163
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:80.2,84.10 5 461163
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:71.20,72.24 1 227806
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:74.3,76.25 3 227806
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:72.25,73.4 0 235421
+github.com/XinFinOrg/XDPoSChain/bmt/bmt_r.go:76.25,78.4 1 222864
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/main.go:36.13,44.2 2 1
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/main.go:62.13,63.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/main.go:63.41,66.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:54.39,60.17 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:65.3,67.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:71.3,72.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:75.3,76.30 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:81.3,81.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:60.17,62.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:67.17,69.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:72.17,74.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:76.30,78.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:78.9,80.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:102.39,107.39 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:110.3,112.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:116.3,117.43 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:120.3,129.30 5 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:140.3,140.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:107.39,109.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:112.17,114.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:117.43,119.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:129.30,131.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:131.9,132.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:137.4,138.59 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:132.19,134.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:134.10,136.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:144.54,145.47 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:157.2,158.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:145.47,146.31 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:149.3,150.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:153.3,153.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:146.31,148.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:150.17,152.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:154.8,154.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/message.go:154.40,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:34.64,37.26 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:47.2,48.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:51.2,51.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:60.2,60.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:37.26,39.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:43.3,43.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:39.17,42.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:48.16,50.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:51.18,53.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:56.3,56.28 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:53.17,55.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:56.28,58.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:70.35,73.2 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:77.44,79.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:82.2,82.26 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/utils.go:79.16,81.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:56.39,59.24 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:62.3,62.49 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:68.3,70.51 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:85.3,95.17 5 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:100.3,100.70 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:103.3,103.70 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:108.3,111.30 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:116.3,116.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:59.24,61.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:62.49,64.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:64.9,64.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:64.33,66.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:70.51,73.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:73.18,75.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:76.9,79.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:79.18,81.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:95.17,97.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:100.70,102.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:103.70,105.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:111.30,113.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/generate.go:113.9,115.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:53.39,58.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:63.3,65.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:70.3,76.18 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:80.3,80.30 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:89.3,89.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:58.17,60.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:65.17,67.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:76.18,78.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:80.30,82.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:82.9,85.19 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/ethkey/inspect.go:85.19,87.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:78.58,80.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:81.57,83.3 1 180
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:84.58,86.68 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:89.3,89.83 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:86.68,88.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:94.71,101.16 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:105.2,111.8 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:101.16,103.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:115.79,127.2 5 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:130.90,134.51 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:154.2,154.20 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:134.51,136.80 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:139.3,140.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:143.3,150.41 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:136.80,138.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:140.17,142.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:150.41,152.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:159.85,161.67 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:165.2,165.79 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:169.2,169.77 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:175.2,175.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:181.2,182.22 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:186.2,186.74 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:190.2,190.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:194.2,194.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:198.2,199.62 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:203.2,203.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:212.2,212.76 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:216.2,216.63 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:220.2,220.47 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:224.2,224.22 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:161.67,163.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:165.79,167.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:169.77,170.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:170.48,172.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:175.45,176.73 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:176.73,178.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:182.22,184.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:186.74,188.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:190.48,192.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:194.48,196.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:199.62,201.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:203.38,206.44 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:209.3,209.34 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:206.44,208.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:212.76,214.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:216.63,218.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:220.47,222.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:230.76,232.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:236.2,236.74 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:240.2,240.67 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:246.2,246.59 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:250.2,251.22 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:255.2,255.64 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:259.2,259.70 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:265.2,265.70 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:271.2,271.61 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:275.2,275.62 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:279.2,279.58 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:283.2,283.61 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:287.2,287.51 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:291.2,291.66 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:295.2,295.22 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:232.56,234.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:236.74,238.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:240.67,241.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:241.48,243.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:246.59,248.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:251.22,253.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:255.64,257.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:259.70,260.61 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:260.61,262.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:265.70,266.61 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:266.61,268.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:271.61,273.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:275.62,277.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:279.58,281.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:283.61,285.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:287.51,289.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:291.66,293.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:300.41,302.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:305.2,307.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:310.2,312.12 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:302.16,304.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:307.16,309.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:316.40,318.55 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:322.2,322.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:318.55,320.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:322.56,324.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:328.53,329.37 1 15
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:336.2,336.12 1 11
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:329.37,330.19 1 15
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:330.19,331.50 1 15
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:331.50,333.5 1 4
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:340.44,342.31 1 15
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:346.2,346.31 1 14
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:350.2,350.31 1 13
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:354.2,354.31 1 12
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:357.2,357.12 1 11
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:342.31,344.3 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:346.31,348.3 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:350.31,352.3 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:354.31,356.3 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:361.48,363.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:366.2,366.20 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/config.go:363.16,365.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:31.33,33.20 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:37.2,38.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:41.2,44.20 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:55.2,56.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:60.2,60.65 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:33.20,35.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:38.16,40.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:44.20,46.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:46.8,48.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:51.3,52.10 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:48.17,50.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:56.16,58.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:63.33,65.20 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:69.2,70.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:73.2,76.20 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:87.2,88.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:92.2,92.65 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:65.20,67.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:70.16,72.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:76.20,78.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:78.8,80.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:83.3,84.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:80.17,82.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:88.16,90.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:95.32,97.20 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:101.2,102.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:105.2,107.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:97.20,99.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:102.16,104.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:110.57,111.67 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:114.2,115.52 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/db.go:111.67,113.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:29.29,31.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:34.2,35.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:38.2,43.16 5 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:31.19,33.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:35.16,37.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:43.16,45.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/hash.go:45.8,47.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:30.29,33.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:38.2,41.20 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:45.2,48.16 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:52.2,55.45 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:58.2,58.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:33.19,35.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:35.8,35.26 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:35.26,37.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:41.20,43.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:48.16,50.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:55.45,57.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/list.go:58.37,60.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:165.13,172.2 5 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:177.13,307.35 4 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:320.2,364.44 5 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:372.2,372.43 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:307.35,309.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:364.44,366.42 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:369.3,370.13 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:366.42,368.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:372.43,375.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:378.13,379.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:379.41,382.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:385.38,388.21 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:391.2,396.12 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:388.21,390.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:399.35,403.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:407.2,411.51 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:415.2,417.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:422.2,428.12 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:438.2,438.31 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:447.2,448.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:403.16,405.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:411.51,413.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:417.16,419.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:428.12,435.3 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:438.31,441.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:441.8,442.31 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:442.31,444.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:451.87,454.63 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:468.2,468.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:454.63,457.30 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:465.3,465.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:457.30,460.18 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:460.18,462.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:468.45,470.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:473.90,475.22 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:479.2,479.58 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:484.2,487.73 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:475.22,477.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:479.58,482.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:490.103,493.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:504.2,504.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:507.2,508.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:511.2,511.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:518.2,519.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:493.34,495.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:495.8,495.71 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:495.71,496.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:496.52,498.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:498.9,500.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:501.8,503.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:504.16,506.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:508.16,510.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:511.25,514.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:514.17,516.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:524.69,526.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:534.2,534.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:537.2,538.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:541.2,541.17 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:526.24,527.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:530.3,530.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:527.25,529.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:534.18,536.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:538.16,540.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:544.55,545.28 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:545.28,547.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:551.3,551.17 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/main.go:547.17,549.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:35.28,37.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:41.2,51.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:57.2,60.19 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:37.19,39.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:51.19,53.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:53.8,55.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:60.19,65.3 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:68.31,71.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:75.2,84.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:90.2,93.19 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:71.19,73.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:84.19,86.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:86.8,88.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:93.19,98.3 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:101.31,103.19 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:107.2,118.19 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:103.19,105.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:118.19,123.3 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:126.83,135.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:140.2,141.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:146.2,146.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:159.2,159.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:183.2,184.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:187.2,187.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:135.16,137.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:141.16,143.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:146.38,147.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:147.25,149.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:149.9,150.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:150.44,152.58 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:152.58,154.6 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:159.33,166.39 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:172.3,172.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:166.39,167.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:170.4,170.54 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:167.43,169.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:173.8,181.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:184.16,186.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:191.86,201.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:208.2,208.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:221.2,221.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:225.2,225.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:242.2,242.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:260.2,261.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:264.2,264.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:201.16,203.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:208.38,209.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:209.25,211.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:211.9,212.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:212.44,214.58 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:214.58,216.6 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:221.56,223.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:225.33,232.39 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:239.3,239.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:232.39,233.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:236.4,236.54 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:233.43,235.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:242.25,245.39 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:257.3,257.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:245.39,246.35 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:246.35,253.5 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:253.10,255.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:261.16,263.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:267.75,277.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:282.2,282.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:295.2,295.61 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:299.2,299.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:315.2,315.30 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:326.2,327.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:330.2,330.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:277.16,279.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:282.38,283.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:283.25,285.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:285.9,286.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:286.44,288.58 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:288.58,290.6 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:295.61,297.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:299.33,306.39 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:312.3,312.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:306.39,307.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:310.4,310.54 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:307.43,309.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:315.30,318.39 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:323.3,323.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:318.39,319.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:319.40,321.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/manifest.go:327.16,329.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:38.31,52.20 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:73.2,73.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:87.2,88.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:94.2,95.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:116.2,117.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:120.2,120.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:52.20,53.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:53.16,55.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:58.4,60.18 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:65.4,65.21 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:55.18,57.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:60.18,62.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:62.10,62.21 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:62.21,64.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:66.9,68.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:69.8,71.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:73.19,75.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:78.3,80.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:83.3,84.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:75.17,77.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:80.17,82.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:88.16,90.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:95.18,96.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:96.37,97.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:100.4,100.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:97.18,99.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:102.8,103.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:103.37,105.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:108.4,109.22 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:112.4,113.31 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:105.18,107.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:109.22,111.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:117.16,119.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:128.34,129.63 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:134.2,134.36 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:129.63,130.36 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:130.36,132.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:137.23,138.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:141.2,141.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:144.2,144.11 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:138.43,140.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:141.44,143.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:147.41,148.42 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:151.2,152.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:155.2,157.32 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:160.2,160.11 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:148.42,150.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:152.16,154.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/swarm/upload.go:157.32,159.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:72.13,87.2 2 1
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:90.47,97.25 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:100.2,101.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:97.25,99.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:568.43,569.60 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:578.2,579.11 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:569.60,570.39 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:573.3,573.39 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:576.3,576.14 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:570.39,572.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:573.39,575.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:585.52,592.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:593.31,594.96 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:595.18,596.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:599.3,599.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:600.17,601.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:604.3,604.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:596.52,598.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:601.52,603.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:609.59,610.72 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:610.72,612.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:617.59,619.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:637.2,638.27 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:620.84,621.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:630.33,631.9 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:632.44,633.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:634.44,635.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:621.44,623.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:623.9,625.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:638.27,640.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:644.3,644.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:640.17,642.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:650.61,652.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:665.2,666.27 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:653.84,654.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:659.40,660.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:661.35,662.9 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:654.44,656.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:656.9,658.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:666.27,668.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:672.3,672.60 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:668.17,670.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:678.58,679.42 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:679.42,681.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:685.48,686.35 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:686.35,689.17 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:692.3,692.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:689.17,691.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:698.42,700.27 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:703.2,703.15 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:700.27,702.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:708.50,709.63 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:716.2,716.39 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:719.2,719.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:722.2,722.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:725.2,725.47 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:709.63,711.46 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:711.46,713.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:716.39,718.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:719.45,721.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:722.38,724.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:725.47,727.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:732.48,733.60 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:740.2,740.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:743.2,743.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:746.2,746.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:733.60,735.45 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:735.45,737.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:740.38,742.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:743.48,745.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:746.37,748.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:753.49,755.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:756.44,757.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:758.41,759.51 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:765.32,767.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:770.2,770.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:775.2,775.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:778.2,778.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:767.16,769.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:770.18,771.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:771.45,773.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:775.18,777.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:783.83,785.34 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:789.2,790.29 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:793.2,800.24 7 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:803.2,803.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:785.34,787.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:790.29,792.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:800.24,802.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:808.77,809.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:809.41,811.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:814.3,814.34 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:811.17,813.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:819.50,821.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:824.2,825.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:828.2,830.23 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:833.2,833.14 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:821.16,823.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:825.16,827.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:830.23,832.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:836.54,847.40 8 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:860.2,860.35 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:863.2,864.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:867.2,869.47 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:872.2,872.57 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:879.2,880.43 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:886.2,886.78 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:894.2,894.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:847.40,849.59 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:849.59,851.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:852.8,853.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:856.3,856.87 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:853.18,855.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:856.87,858.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:860.35,862.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:864.17,866.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:869.47,871.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:872.57,874.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:880.43,882.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:882.8,882.29 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:882.29,884.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:886.78,888.17 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:891.3,891.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:888.17,890.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:894.40,900.3 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:904.56,911.9 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:922.2,922.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:925.2,925.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:928.2,928.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:931.2,931.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:912.41,913.51 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:914.42,915.19 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:916.40,917.64 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:918.40,919.64 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:922.43,924.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:925.40,927.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:928.37,930.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:931.43,933.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:936.53,937.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:940.2,940.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:937.41,939.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:940.45,942.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:945.58,946.46 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:949.2,949.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:952.2,952.47 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:955.2,955.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:958.2,958.47 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:961.2,961.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:964.2,964.49 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:967.2,967.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:970.2,970.49 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:973.2,973.46 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:946.46,948.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:949.45,951.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:952.47,954.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:955.48,957.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:958.47,960.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:961.50,963.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:964.49,966.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:967.50,969.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:970.49,972.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:973.46,975.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:978.51,979.46 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:982.2,982.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:985.2,985.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:988.2,988.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:991.2,991.54 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:994.2,994.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:979.46,981.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:982.48,984.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:985.52,987.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:988.50,990.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:991.54,993.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:994.52,996.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1002.60,1004.33 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1032.2,1032.18 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1004.33,1007.10 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1011.3,1013.22 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1028.3,1028.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1007.10,1008.74 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1013.22,1014.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1015.16,1017.51 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1020.5,1020.8 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1022.18,1022.18 0 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1023.12,1024.92 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1017.51,1019.6 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1028.38,1030.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1032.18,1034.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1038.76,1039.53 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1042.2,1042.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1039.53,1041.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1042.45,1044.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1047.78,1048.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1062.2,1063.45 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1068.2,1068.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1073.2,1073.52 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1078.2,1078.53 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1048.44,1050.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1050.8,1056.73 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1056.73,1058.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1058.9,1060.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1063.45,1065.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1065.8,1067.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1068.43,1070.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1070.8,1072.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1073.52,1075.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1075.8,1077.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1078.53,1080.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1084.72,1097.9 10 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1105.2,1105.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1108.2,1108.42 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1111.2,1111.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1115.2,1115.80 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1118.2,1120.90 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1123.2,1125.74 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1128.2,1128.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1131.2,1131.39 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1134.2,1134.41 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1137.2,1137.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1140.2,1140.45 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1144.2,1144.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1151.2,1151.9 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1098.42,1099.85 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1100.41,1101.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1102.42,1103.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1105.41,1107.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1108.42,1110.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1111.41,1113.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1115.80,1117.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1120.90,1122.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1125.74,1127.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1128.45,1130.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1131.39,1133.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1134.41,1136.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1137.40,1139.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1140.45,1143.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1144.43,1146.70 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1146.70,1148.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1152.40,1153.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1156.3,1156.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1157.40,1158.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1161.3,1161.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1162.42,1168.43 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1176.3,1176.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1179.3,1182.42 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1153.43,1155.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1158.43,1160.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1168.43,1170.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1170.9,1172.18 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1172.18,1174.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1176.50,1178.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1182.42,1184.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1190.37,1193.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1196.75,1202.40 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1205.2,1206.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1209.2,1209.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1202.40,1204.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1206.16,1208.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1212.50,1214.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1222.2,1222.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1215.40,1216.46 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1217.40,1218.46 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1219.42,1220.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1226.101,1231.16 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1234.2,1235.24 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1251.2,1251.90 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1254.2,1259.74 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1262.2,1264.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1267.2,1267.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1231.16,1233.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1235.24,1237.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1237.8,1239.40 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1249.3,1249.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1239.40,1248.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1251.90,1253.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1259.74,1261.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1264.16,1266.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1272.53,1274.48 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1278.2,1281.80 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1284.2,1284.17 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1274.48,1276.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1281.80,1283.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1300.81,1301.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1301.38,1302.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1307.3,1307.21 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1302.40,1303.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1303.23,1305.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1312.56,1314.82 2 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1328.2,1328.16 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1331.2,1331.21 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1314.82,1315.17 1 4
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1318.3,1318.19 1 4
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1321.3,1321.79 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1326.3,1326.13 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1315.17,1317.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1318.19,1320.4 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1321.79,1323.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1323.9,1323.21 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1323.21,1325.4 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/utils/flags.go:1328.16,1330.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:15.60,17.42 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:35.2,35.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:17.42,18.77 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:18.77,20.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:21.8,22.77 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:22.77,28.44 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:32.4,32.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:28.44,31.5 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:35.16,37.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:41.64,42.78 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:42.78,44.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:44.17,46.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:51.60,52.80 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:52.80,61.3 5 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:61.17,63.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:66.64,68.78 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:75.2,75.78 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:68.78,70.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:70.17,72.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:75.78,77.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/utils.go:77.17,79.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:48.49,50.31 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:61.2,62.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:50.31,54.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:54.8,57.60 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:57.60,59.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:65.34,66.38 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:69.2,69.12 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:66.38,68.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:69.12,76.27 7 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:82.3,83.26 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:76.27,78.13 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:78.13,80.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:87.59,95.12 6 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:101.2,101.32 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:110.2,114.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:117.2,120.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:125.2,130.28 4 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:167.2,167.12 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:95.12,96.31 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:99.3,99.14 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:96.31,98.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:101.32,102.10 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:103.15,104.15 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:105.11,106.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:114.16,116.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:120.34,121.55 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:121.55,123.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:130.28,132.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:135.3,136.34 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:151.3,151.13 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:155.3,155.23 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:158.3,159.24 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:163.3,163.55 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:132.23,134.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:136.34,138.47 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:144.4,144.26 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:148.4,149.7 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:138.47,139.10 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:140.10,140.25 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:140.25,142.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:144.26,146.13 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:151.13,152.9 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:155.23,157.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:159.24,161.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:163.55,165.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:170.82,172.31 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:185.2,185.12 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:172.31,174.43 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:181.3,181.67 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:174.43,175.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:178.4,178.12 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:175.56,177.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:181.67,183.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:190.64,195.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:198.2,201.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:206.2,206.50 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:209.2,211.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:195.16,197.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:201.34,204.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:206.50,208.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:216.97,221.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:224.2,227.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:232.2,232.64 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:235.2,236.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:221.16,223.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:227.34,230.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:232.64,234.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:240.58,245.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:248.2,251.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:256.2,261.6 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:281.2,281.24 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:284.2,284.12 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:245.16,247.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:251.34,252.55 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:252.55,254.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:261.6,265.46 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:272.3,273.28 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:265.46,266.21 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:269.4,269.14 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:266.21,267.10 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:273.28,274.64 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:277.4,277.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:274.64,276.5 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:281.24,283.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:289.58,294.16 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:297.2,300.34 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:305.2,306.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:311.2,312.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:294.16,296.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:300.34,303.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:306.16,307.56 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/cmd.go:307.56,309.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:41.46,43.2 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:45.54,48.2 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:58.43,60.31 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:63.2,63.87 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:60.31,62.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:66.49,68.29 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:68.29,71.3 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:76.52,77.40 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:77.40,79.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:92.43,93.16 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:96.2,97.21 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:93.16,95.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:100.47,102.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:111.45,113.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:115.44,117.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:119.53,120.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:120.37,122.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:126.71,128.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:131.2,131.33 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:128.16,130.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:145.36,146.14 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:149.2,149.31 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:146.14,148.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:152.40,154.9 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:157.2,158.12 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:154.9,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:161.35,163.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:165.34,167.20 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:170.2,170.72 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:167.20,169.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:173.43,174.37 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:174.37,176.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:180.56,182.16 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:185.2,185.36 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:182.16,184.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:188.45,189.20 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:195.2,195.8 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:189.20,191.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:191.8,193.3 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:198.55,200.29 2 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:207.2,207.8 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:200.29,203.23 3 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:203.23,205.4 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:210.44,212.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:214.46,216.2 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:223.34,224.63 1 5
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:229.2,229.36 1 5
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:224.63,225.36 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:225.36,227.4 1 1
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:232.23,233.43 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:236.2,236.44 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:239.2,239.11 1 0
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:233.43,235.3 1 2
+github.com/XinFinOrg/XDPoSChain/cmd/utils/customflags.go:236.44,238.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:29.44,31.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:33.38,35.38 2 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:39.2,39.13 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:35.38,37.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:42.59,43.30 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:46.2,46.41 1 0
+github.com/XinFinOrg/XDPoSChain/common/path.go:43.30,45.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:26.51,28.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:31.2,31.53 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:38.2,38.12 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:28.16,30.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:31.53,32.51 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:36.3,36.65 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:32.51,35.4 2 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:42.53,44.33 2 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:52.2,52.8 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:44.33,45.25 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:48.3,48.16 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:45.25,47.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/test_utils.go:48.16,50.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:22.29,25.19 2 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:28.2,28.19 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:25.19,27.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:31.31,32.16 1 83
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:37.2,37.19 1 83
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:40.2,40.21 1 83
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:32.16,33.39 1 82
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:33.39,35.4 1 82
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:37.19,39.3 1 11
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:46.47,47.14 1 1
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:50.2,53.8 3 1
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:47.14,49.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:56.36,58.2 1 9
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:60.34,62.2 1 219
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:64.29,65.21 1 14
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:68.2,68.32 1 12
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:73.2,73.13 1 9
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:65.21,67.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:68.32,69.25 1 219
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:69.25,71.4 1 3
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:76.33,78.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:80.35,84.2 2 83
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:86.50,88.20 2 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:88.20,90.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:90.8,91.20 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:91.20,93.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:93.9,97.4 3 0
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:101.48,102.21 1 2
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:106.2,109.15 3 1
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:102.21,104.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:112.47,113.21 1 2
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:117.2,120.15 3 1
+github.com/XinFinOrg/XDPoSChain/common/bytes.go:113.21,115.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/debug.go:28.35,38.2 6 0
+github.com/XinFinOrg/XDPoSChain/common/debug.go:41.42,52.2 3 0
+github.com/XinFinOrg/XDPoSChain/common/format.go:34.41,36.65 2 0
+github.com/XinFinOrg/XDPoSChain/common/format.go:39.2,39.14 1 0
+github.com/XinFinOrg/XDPoSChain/common/format.go:36.65,38.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/size.go:28.38,29.17 1 3
+github.com/XinFinOrg/XDPoSChain/common/size.go:29.17,31.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/size.go:31.8,31.21 1 2
+github.com/XinFinOrg/XDPoSChain/common/size.go:31.21,33.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/size.go:33.8,35.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/size.go:40.46,41.17 1 0
+github.com/XinFinOrg/XDPoSChain/common/size.go:41.17,43.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/size.go:43.8,43.21 1 0
+github.com/XinFinOrg/XDPoSChain/common/size.go:43.21,45.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/size.go:45.8,47.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:66.33,70.2 3 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:71.34,71.67 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:72.34,72.67 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:73.34,73.91 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:74.34,74.68 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:77.30,77.53 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:78.30,78.45 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:79.30,79.68 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:80.30,80.61 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:84.39,86.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:90.31,92.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:96.43,98.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:101.50,103.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:106.50,108.2 1 6
+github.com/XinFinOrg/XDPoSChain/common/types.go:111.45,113.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:116.35,117.21 1 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:121.2,121.32 1 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:117.21,119.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:125.36,125.61 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:128.32,129.26 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:129.26,131.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:135.65,137.34 2 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:140.2,140.27 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:137.34,139.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:143.29,145.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:151.60,153.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:156.55,158.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:165.39,169.2 3 80
+github.com/XinFinOrg/XDPoSChain/common/types.go:170.40,170.76 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:171.40,171.76 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:172.40,172.77 1 80
+github.com/XinFinOrg/XDPoSChain/common/types.go:176.34,177.21 1 9
+github.com/XinFinOrg/XDPoSChain/common/types.go:180.2,180.46 1 9
+github.com/XinFinOrg/XDPoSChain/common/types.go:177.21,179.3 1 7
+github.com/XinFinOrg/XDPoSChain/common/types.go:184.33,184.56 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:185.33,185.48 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:186.33,186.71 1 2
+github.com/XinFinOrg/XDPoSChain/common/types.go:187.33,187.61 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:190.31,197.35 6 8
+github.com/XinFinOrg/XDPoSChain/common/types.go:208.2,208.30 1 8
+github.com/XinFinOrg/XDPoSChain/common/types.go:197.35,199.15 2 320
+github.com/XinFinOrg/XDPoSChain/common/types.go:204.3,204.38 1 320
+github.com/XinFinOrg/XDPoSChain/common/types.go:199.15,201.4 1 160
+github.com/XinFinOrg/XDPoSChain/common/types.go:201.9,203.4 1 160
+github.com/XinFinOrg/XDPoSChain/common/types.go:204.38,206.4 1 41
+github.com/XinFinOrg/XDPoSChain/common/types.go:212.34,214.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:218.46,220.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:223.38,224.21 1 80
+github.com/XinFinOrg/XDPoSChain/common/types.go:227.2,227.35 1 80
+github.com/XinFinOrg/XDPoSChain/common/types.go:224.21,226.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:231.39,231.64 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:234.38,235.26 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:235.26,237.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:241.48,243.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:246.53,248.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:251.53,253.2 1 6
+github.com/XinFinOrg/XDPoSChain/common/types.go:259.63,261.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:264.58,266.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:269.70,270.21 1 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:274.2,274.29 1 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:282.2,282.14 1 1
+github.com/XinFinOrg/XDPoSChain/common/types.go:270.21,272.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:274.29,275.40 1 3
+github.com/XinFinOrg/XDPoSChain/common/types.go:275.40,276.24 1 10
+github.com/XinFinOrg/XDPoSChain/common/types.go:276.24,278.5 1 3
+github.com/XinFinOrg/XDPoSChain/common/types.go:286.56,288.35 2 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:291.2,291.13 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:288.35,290.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:294.62,295.64 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:298.2,299.38 2 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:302.2,302.18 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:295.64,297.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/types.go:299.38,301.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:20.37,21.23 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:24.2,24.32 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:21.23,23.3 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:29.41,31.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:34.2,35.11 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:43.2,43.38 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:46.2,46.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:31.16,33.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:35.11,39.26 4 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:39.26,41.4 1 1016
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:43.38,45.3 1 50
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:51.41,53.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:56.2,56.25 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:59.2,59.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:53.16,55.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:56.25,58.3 1 8178
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:64.37,65.23 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:68.2,68.32 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:65.23,67.3 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:73.41,75.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:78.2,79.11 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:87.2,87.38 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:90.2,90.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:75.16,77.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:79.11,83.26 4 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:83.26,85.4 1 1016
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:87.38,89.3 1 50
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:95.41,97.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:100.2,100.25 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:103.2,103.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:97.16,99.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:100.25,102.3 1 8178
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:108.36,109.23 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:112.2,112.31 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:109.23,111.3 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:117.40,119.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:122.2,123.11 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:131.2,131.38 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:134.2,134.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:119.16,121.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:123.11,127.26 4 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:127.26,129.4 1 1016
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:131.38,133.3 1 50
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:139.40,141.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:144.2,144.25 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:147.2,147.10 1 8
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:141.16,143.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:144.25,146.3 1 8178
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:151.31,152.23 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:155.2,155.25 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:152.23,154.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:160.35,163.11 3 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:171.2,171.38 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:176.2,176.14 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:163.11,165.26 2 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:165.26,166.18 1 280
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:166.18,168.5 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:171.38,172.16 1 13
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:172.16,174.4 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:181.35,182.30 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:187.2,187.14 1 0
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:182.30,183.16 1 2247
+github.com/XinFinOrg/XDPoSChain/common/bitutil/bitutil.go:183.16,185.4 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:60.40,61.58 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:64.2,66.12 3 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:61.58,63.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:71.44,73.20 1 98
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:77.2,77.20 1 97
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:84.2,87.25 3 71
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:93.2,93.28 1 71
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:96.2,96.66 1 67
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:73.20,75.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:77.20,78.19 1 26
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:81.3,81.14 1 25
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:78.19,80.4 1 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:87.25,88.13 1 63587
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:88.13,91.4 2 452
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:93.28,95.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:102.63,103.24 1 3
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:106.2,106.25 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:111.2,111.40 1 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:103.24,105.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:106.25,110.3 3 1
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:115.65,117.16 2 43
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:120.2,120.23 1 34
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:123.2,123.17 1 30
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:117.16,119.3 1 9
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:120.23,122.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:130.77,132.17 1 154
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:136.2,137.20 2 151
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:140.2,140.17 1 146
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:148.2,149.16 2 111
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:152.2,152.44 1 86
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:169.2,169.25 1 77
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:132.17,134.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:137.20,139.3 1 5
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:140.17,142.19 2 35
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:145.3,145.24 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:142.19,144.4 1 33
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:149.16,151.3 1 25
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:152.44,153.47 1 81157
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:153.47,155.24 1 514
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:158.4,158.24 1 508
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:162.4,162.22 1 506
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:165.4,166.9 2 505
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:155.24,157.5 1 6
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:158.24,160.5 1 2
+github.com/XinFinOrg/XDPoSChain/common/bitutil/compress.go:162.22,164.5 1 1
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:65.40,70.47 2 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:73.2,73.10 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:70.47,72.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:77.54,78.16 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:81.2,85.16 5 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:88.2,89.23 2 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:92.2,93.57 2 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:96.2,96.57 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:99.2,99.57 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:102.2,102.15 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:78.16,80.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:85.16,87.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:89.23,91.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:93.57,95.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:96.57,98.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:99.57,101.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:106.79,107.22 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:110.2,111.16 2 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:114.2,117.27 4 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:107.22,109.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:111.16,113.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:121.88,122.27 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:125.2,126.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:129.2,130.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:133.2,135.27 3 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:122.27,124.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:126.16,128.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:130.16,132.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:138.84,142.34 4 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:145.2,146.64 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:151.2,152.43 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:181.2,181.23 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:142.34,144.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:146.64,148.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:152.43,155.64 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:158.3,159.72 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:162.3,163.70 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:166.3,179.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:155.64,157.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:159.72,161.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:163.70,165.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:184.49,186.29 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:193.2,193.29 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:186.29,188.17 2 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:191.3,191.24 1 0
+github.com/XinFinOrg/XDPoSChain/common/compiler/solidity.go:188.17,190.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:25.30,28.73 2 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:32.2,33.21 2 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:36.2,36.73 1 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:39.2,39.12 1 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:28.73,30.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:33.21,35.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:36.73,38.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:44.29,46.73 2 2
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:49.2,49.28 1 2
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:46.73,48.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:54.29,56.73 2 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:59.2,59.28 1 1
+github.com/XinFinOrg/XDPoSChain/common/fdlimit/fdlimit_unix.go:56.73,58.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:56.36,56.54 1 90
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:59.43,60.21 1 12
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:63.2,63.25 1 11
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:66.2,67.16 2 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:70.2,70.15 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:60.21,62.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:63.25,65.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:67.16,69.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:74.38,76.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:79.2,79.12 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:76.16,77.13 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:83.30,88.2 4 7
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:91.49,93.16 2 13
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:96.2,97.16 2 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:100.2,100.17 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:93.16,95.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:97.16,99.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:105.44,107.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:110.2,110.12 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:107.16,108.13 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:114.36,118.2 3 12
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:122.13,126.23 2 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:127.9,128.22 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:129.9,130.21 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:131.10,132.31 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:138.48,140.16 2 16
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:143.2,143.19 1 13
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:146.2,148.23 3 12
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:163.2,164.17 2 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:140.16,142.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:143.19,145.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:148.23,150.16 2 19
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:153.3,153.35 1 19
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:161.3,161.14 1 17
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:150.16,152.4 1 12
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:153.35,155.24 2 161
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:158.4,159.29 2 159
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:155.24,157.5 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:169.43,171.16 2 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:174.2,174.12 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:171.16,172.13 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:179.40,181.16 2 18
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:184.2,184.35 1 15
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:181.16,183.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:187.37,189.2 1 40
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:191.56,192.21 1 29
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:195.2,195.25 1 29
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:198.2,199.21 2 27
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:202.2,202.39 1 25
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:205.2,205.19 1 23
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:192.21,194.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:195.25,197.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:199.21,201.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:202.39,204.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:210.35,211.9 1 455
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:212.30,213.26 1 127
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:214.30,215.31 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:216.30,217.31 1 308
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:218.10,219.19 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:223.32,224.44 1 9
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:232.2,232.45 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:235.2,235.26 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:238.2,238.12 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:224.44,225.18 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:226.25,227.25 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:228.26,229.20 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:232.45,234.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/hexutil.go:235.26,237.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:40.46,45.2 4 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:48.51,49.22 1 12
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:52.2,52.70 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:49.22,51.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:56.51,58.16 2 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:61.2,62.47 2 8
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:67.2,67.12 1 8
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:58.16,60.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:62.47,64.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:64.8,66.3 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:71.32,73.2 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:78.68,79.22 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:82.2,82.89 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:79.22,81.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:88.66,90.16 2 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:93.2,93.28 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:97.2,97.24 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:102.2,103.12 2 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:90.16,92.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:93.28,95.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:97.24,98.35 1 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:98.35,100.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:109.76,111.16 2 8
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:114.2,114.28 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:118.2,118.24 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:123.2,124.12 2 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:111.16,113.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:114.28,116.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:118.24,119.35 1 30
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:119.35,121.4 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:136.44,138.2 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:141.49,142.22 1 19
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:145.2,145.68 1 17
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:142.22,144.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:149.49,151.16 2 17
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:154.2,154.19 1 14
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:157.2,159.23 3 13
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:174.2,177.12 4 11
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:151.16,153.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:154.19,156.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:159.23,161.16 2 20
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:164.3,164.35 1 20
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:172.3,172.14 1 18
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:161.16,163.4 1 13
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:164.35,166.24 2 161
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:169.4,170.29 2 159
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:166.24,168.5 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:181.32,183.2 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:186.31,188.2 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:195.47,200.2 4 8
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:203.52,204.22 1 16
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:207.2,207.71 1 14
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:204.22,206.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:211.52,213.16 2 30
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:216.2,216.19 1 24
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:219.2,220.27 2 22
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:228.2,229.12 2 18
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:213.16,215.3 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:216.19,218.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:220.27,222.23 2 93
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:225.3,226.13 2 89
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:222.23,224.4 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:233.33,235.2 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:242.45,244.2 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:247.50,248.22 1 18
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:251.2,251.69 1 16
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:248.22,250.3 1 2
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:255.50,258.53 3 16
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:263.2,264.12 2 10
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:258.53,260.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:260.8,260.23 1 15
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:260.23,262.3 1 5
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:268.31,270.2 1 4
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:272.34,274.2 1 65
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:276.43,278.2 1 63
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:280.63,281.21 1 20
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:284.2,284.30 1 19
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:289.2,289.23 1 18
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:292.2,292.19 1 15
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:281.21,283.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:284.30,286.3 1 13
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:286.8,286.23 1 6
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:286.23,288.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:289.23,291.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:295.60,296.21 1 47
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:299.2,299.31 1 44
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:302.2,303.21 2 41
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:306.2,306.39 1 38
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:309.2,309.19 1 35
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:296.21,298.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:299.31,301.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:303.21,305.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:306.39,308.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:312.55,313.34 1 81
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:316.2,316.12 1 35
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:313.34,315.3 1 46
+github.com/XinFinOrg/XDPoSChain/common/hexutil/json.go:319.43,321.2 1 16
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:44.60,46.9 2 12
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:49.2,50.12 2 9
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:46.9,48.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:54.55,56.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:60.43,61.13 1 14
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:64.2,64.53 1 13
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:68.2,69.22 2 7
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:61.13,63.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:64.53,67.3 2 6
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:73.39,75.9 2 2
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:78.2,78.10 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:75.9,76.49 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:84.42,86.2 1 2
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:89.42,91.2 1 2
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:94.42,95.22 1 4
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:98.2,98.31 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/integer.go:95.22,97.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:45.61,47.9 2 13
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:50.2,51.12 2 10
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:47.9,49.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:55.57,56.14 1 0
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:59.2,59.55 1 0
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:56.14,58.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:64.45,65.13 1 16
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:68.2,70.53 3 15
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:75.2,75.33 1 15
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:78.2,78.19 1 15
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:65.13,67.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:70.53,72.3 1 6
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:72.8,74.3 1 9
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:75.33,77.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:82.41,84.9 2 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:87.2,87.10 1 2
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:84.9,85.41 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:91.34,94.2 2 17
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:97.37,98.18 1 2
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:101.2,101.10 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:98.18,100.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:105.37,106.18 1 2
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:109.2,109.10 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:106.18,108.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:113.34,114.34 1 4
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:119.2,119.19 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:114.34,115.19 1 12
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:115.19,117.4 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:124.52,125.28 1 4
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:128.2,130.12 3 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:125.28,127.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:136.51,140.21 3 23
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:143.2,147.28 3 13
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:140.21,142.3 1 10
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:154.51,155.20 1 17
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:158.2,158.47 1 14
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:155.20,157.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:163.44,165.34 2 6
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:165.34,166.43 1 12
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:166.43,170.4 3 80
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:175.32,177.2 1 276
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:186.32,187.22 1 7
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:187.22,189.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:189.8,191.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:199.44,202.39 2 6
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:211.2,211.15 1 6
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:202.39,203.33 1 4
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:203.33,204.19 1 256
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:207.4,208.14 2 256
+github.com/XinFinOrg/XDPoSChain/common/math/big.go:204.19,206.5 1 12
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:30.20,32.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:35.47,37.2 1 7
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:40.48,42.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:76.31,78.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:81.40,83.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:86.53,88.32 2 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:97.2,97.28 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:88.32,92.10 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:93.22,93.22 0 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:94.11,94.11 0 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:101.55,103.27 2 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:104.2,104.11 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:103.27,103.44 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:108.60,110.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:117.47,119.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/mclock.go:121.43,123.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:50.28,51.19 1 17
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:51.19,53.3 1 5
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:57.42,63.55 5 10
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:67.2,70.24 3 10
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:63.55,66.3 2 6
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:70.24,72.3 1 6
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:76.40,81.2 3 2
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:84.42,89.27 4 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:89.27,91.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:95.35,100.2 3 5
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:103.44,105.2 1 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:108.57,114.31 5 4
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:115.2,116.14 2 4
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:114.31,114.49 1 5
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:121.59,123.2 1 2
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:127.65,132.2 3 2
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:134.68,142.2 6 6
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:144.33,148.18 3 4
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:151.2,154.13 4 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:148.18,150.3 1 3
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:157.44,158.18 1 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:162.2,165.18 4 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:170.2,170.23 1 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:158.18,159.57 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:165.18,167.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:167.8,169.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:173.40,174.18 1 5
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:177.2,177.14 1 5
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:174.18,175.53 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:182.34,184.2 1 14
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:186.44,188.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:190.39,194.2 3 6
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:196.44,200.2 3 7
+github.com/XinFinOrg/XDPoSChain/common/mclock/simclock.go:202.42,209.2 6 7
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:29.42,32.2 2 6
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:34.40,35.26 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:35.26,37.3 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:37.8,40.3 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:55.64,56.31 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:56.31,58.3 1 4
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:62.31,64.2 1 16
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:67.30,69.2 1 4
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:72.27,73.56 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:73.56,73.68 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:77.44,80.2 2 2
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:83.44,86.2 2 2
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:89.44,92.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:95.44,98.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:101.44,104.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:107.49,110.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:113.44,116.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:121.41,124.2 2 2
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:127.45,130.2 2 2
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:137.37,139.2 1 8
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:144.34,146.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:149.33,151.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:154.34,156.2 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:159.32,161.2 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:164.35,166.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:169.36,171.2 1 1
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:174.36,175.38 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:181.2,181.23 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:175.38,176.23 1 0
+github.com/XinFinOrg/XDPoSChain/common/number/int.go:176.23,178.4 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:55.166,66.2 4 1
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:69.29,72.2 2 1
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:75.31,77.28 2 1000
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:80.2,82.40 3 1000
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:77.28,79.3 1 756398
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:86.44,88.2 1 1042458
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:91.39,93.2 1 272488
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:96.48,101.57 2 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:106.2,106.24 1 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:101.57,105.3 3 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:111.37,112.27 1 22595
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:118.2,118.27 1 216
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:121.2,121.11 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:112.27,113.99 1 22379
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:116.3,116.11 1 9365
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:113.99,115.4 1 13014
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:118.27,120.3 1 216
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:127.84,130.22 3 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:130.22,134.129 4 12572
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:134.129,136.38 2 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:136.38,137.31 1 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:140.5,140.11 1 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:137.31,139.6 1 2549
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:147.43,150.2 2 10023
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:153.51,154.15 1 272488
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:157.2,157.76 1 272488
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:154.15,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:161.34,163.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:166.32,168.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:171.60,172.17 1 8523799
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:172.17,174.3 1 521270
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:174.8,176.3 1 8002529
+github.com/XinFinOrg/XDPoSChain/common/prque/lazyqueue.go:180.60,182.2 1 8502399
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:30.44,32.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:35.56,37.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:40.45,43.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:47.44,50.2 2 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:53.39,55.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:58.43,59.11 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:62.2,62.31 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:59.11,61.3 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:66.30,68.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:71.28,73.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/prque.go:76.25,78.2 1 0
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:44.51,51.2 6 3
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:55.41,56.26 1 1055030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:65.2,65.23 1 1055030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:68.2,70.10 3 1055030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:56.26,61.3 4 0
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:61.8,61.34 1 1055030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:61.34,64.3 2 0
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:65.23,67.3 1 1042458
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:75.42,78.18 3 1054030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:82.2,83.23 2 1054030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:86.2,86.8 1 1054030
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:78.18,81.3 2 0
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:83.23,85.3 1 1041458
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:90.28,92.2 1 2936792
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:96.38,98.2 1 13472063
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:101.33,104.23 3 7485765
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:108.2,108.43 1 7485765
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:104.23,107.3 2 7471141
+github.com/XinFinOrg/XDPoSChain/common/prque/sstack.go:112.26,114.2 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:37.45,40.32 2 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:62.2,62.25 1 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:40.32,41.22 1 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:41.22,42.22 1 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:42.22,43.21 1 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:53.5,53.8 1 4
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:44.24,45.22 1 1
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:46.28,47.26 1 1
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:48.21,49.26 1 1
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:50.13,51.46 1 1
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:54.10,56.5 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:57.9,59.4 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:65.52,66.9 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:67.23,68.38 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:69.54,71.32 2 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:77.3,77.39 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:78.22,79.57 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:84.3,84.14 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:85.10,86.20 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:71.32,72.19 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:75.4,75.7 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:72.19,73.10 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:79.57,81.4 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:81.9,81.72 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:81.72,83.4 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:90.34,94.19 3 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:100.2,100.20 1 0
+github.com/XinFinOrg/XDPoSChain/compression/rle/read_write.go:94.19,98.3 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:53.37,55.22 2 416
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:58.2,58.29 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:55.22,57.3 1 416
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:64.38,66.65 2 2048
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:69.2,69.13 1 2048
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:66.65,68.3 1 11876
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:74.39,76.22 2 806
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:79.2,79.31 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:76.22,78.3 1 806
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:85.40,87.64 2 2048
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:90.2,90.13 1 2048
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:87.64,89.3 1 15226
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:100.37,101.40 1 7921
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:101.40,105.3 3 18070779
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:110.36,112.25 2 7028
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:115.2,116.46 2 6901
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:119.2,119.13 1 6901
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:112.25,114.3 1 127
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:116.46,118.3 1 253935
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:128.62,133.15 3 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:143.2,158.12 10 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:169.2,173.70 3 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:178.2,180.35 2 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:194.2,194.23 1 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:133.15,137.30 3 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:140.3,140.90 1 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:137.30,139.4 1 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:158.12,159.7 1 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:159.7,160.11 1 146
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:161.16,162.11 1 143
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:163.39,164.172 1 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:173.70,176.3 2 4401012
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:180.35,181.29 1 429
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:181.29,191.4 4 13203465
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:194.23,196.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:200.26,201.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:201.38,203.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:209.41,210.33 1 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:210.33,212.3 1 8704
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:219.30,221.2 1 27245456
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:224.43,225.32 1 27223424
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:225.32,227.3 1 436514816
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:232.81,240.33 4 106112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:243.2,247.35 3 106112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:251.2,251.46 1 106112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:256.2,256.29 1 106112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:259.2,260.12 2 106112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:240.33,242.3 1 1591680
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:247.35,249.3 1 1697792
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:251.46,254.3 2 27164672
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:256.29,258.3 1 1697792
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:265.67,270.15 3 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:281.2,297.31 11 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:327.2,327.13 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:270.15,274.30 3 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:277.3,277.90 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:274.30,276.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:297.31,298.19 1 72
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:298.19,308.38 6 72
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:312.4,313.47 2 72
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:308.38,310.5 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:313.47,315.16 2 3072
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:318.5,320.70 2 3072
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:315.16,317.6 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:320.70,322.6 1 612
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:332.109,346.32 8 918
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:350.2,352.36 2 918
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:360.2,360.35 1 918
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:363.2,366.26 3 918
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:369.2,369.58 1 918
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:346.32,348.3 1 29376
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:352.36,354.51 2 58752
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:357.3,357.21 1 58752
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:354.51,356.4 1 117504
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:360.35,362.3 1 7344
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:366.26,368.3 1 7344
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:375.94,378.40 2 805
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:387.2,387.45 1 805
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:378.40,382.34 3 103040
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:385.3,385.14 1 103040
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:382.34,384.4 1 1648640
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:393.82,394.40 1 113
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:398.2,398.63 1 113
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/algorithm.go:394.40,397.3 2 14464
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:63.76,65.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:69.104,71.43 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:75.2,76.51 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:79.2,80.19 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:84.2,84.64 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:71.43,73.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:76.51,78.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:80.19,82.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:90.137,92.64 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:101.2,102.28 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:107.2,113.31 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:122.2,123.12 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:149.2,149.25 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:92.64,94.37 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:97.3,97.24 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:94.37,96.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:102.28,104.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:113.31,114.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:114.13,115.30 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:115.30,118.5 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:123.12,130.7 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:130.7,131.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:132.22,133.33 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:137.25,138.52 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:144.17,145.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:133.33,136.6 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:138.52,140.31 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:140.31,142.7 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:152.127,154.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:159.2,159.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:162.2,162.83 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:165.2,165.80 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:154.16,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:156.8,156.65 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:156.65,158.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:159.19,161.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:162.83,164.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:170.91,172.43 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:176.2,176.37 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:180.2,183.25 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:194.2,198.39 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:217.2,217.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:172.43,174.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:176.37,178.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:183.25,185.22 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:188.3,189.43 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:192.3,192.51 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:185.22,186.9 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:189.43,191.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:198.39,201.28 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:204.3,207.29 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:210.3,210.83 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:213.3,213.100 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:201.28,203.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:207.29,209.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:210.83,212.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:213.100,215.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:223.124,225.61 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:229.2,229.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:238.2,238.39 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:242.2,244.42 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:248.2,249.27 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:253.2,253.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:258.2,259.14 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:262.2,264.67 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:268.2,268.90 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:272.2,272.10 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:278.2,278.78 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:281.2,281.77 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:284.2,284.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:225.61,227.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:229.11,230.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:230.42,232.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:233.8,234.85 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:234.85,236.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:238.39,240.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:244.42,246.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:249.27,251.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:253.38,255.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:259.14,261.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:264.67,266.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:268.90,270.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:272.10,273.58 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:273.58,275.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:278.78,280.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:281.77,283.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:290.111,292.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:297.93,299.9 2 14
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:300.32,301.47 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:302.32,303.47 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:304.10,305.46 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:323.74,340.46 7 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:346.2,346.27 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:350.2,355.41 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:361.2,362.40 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:366.2,371.31 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:376.2,376.10 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:340.46,342.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:342.8,344.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:346.27,348.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:355.41,357.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:362.40,364.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:371.31,375.3 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:382.74,402.27 8 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:406.2,411.41 4 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:415.2,420.31 3 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:425.2,425.10 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:402.27,404.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:411.41,413.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:420.31,424.3 3 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:431.73,440.71 7 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:445.2,445.44 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:449.2,451.31 3 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:458.2,458.13 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:440.71,442.3 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:442.8,444.3 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:445.44,447.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:451.31,457.3 4 10
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:463.91,465.80 1 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:473.2,473.26 1 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:477.2,477.35 1 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:481.2,485.39 4 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:488.2,493.47 3 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:496.2,497.51 2 4
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:500.2,500.12 1 4
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:465.80,467.48 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:470.3,470.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:467.48,469.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:473.26,475.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:477.35,479.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:485.39,487.3 1 801
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:493.47,495.3 1 800
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:497.51,499.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:505.88,507.19 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:510.2,511.12 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:507.19,509.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:516.232,523.2 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:534.120,537.39 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:541.2,543.31 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:553.2,553.43 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:537.39,539.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/consensus.go:543.31,552.3 7 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:61.28,64.2 2 563
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:67.68,69.16 2 543
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:72.2,73.16 2 411
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:77.2,77.34 1 411
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:84.2,84.48 1 411
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:69.16,71.3 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:73.16,76.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:77.34,78.25 1 822
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:78.25,82.4 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:88.76,91.11 2 543
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:94.2,95.16 2 543
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:99.2,103.56 4 543
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:91.11,93.3 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:95.16,97.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:109.125,111.62 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:115.2,118.16 3 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:121.2,121.76 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:125.2,126.16 2 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:130.2,135.36 4 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:138.2,138.37 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:141.2,141.46 1 132
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:144.2,144.24 1 129
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:111.62,113.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:118.16,120.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:121.76,123.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:126.16,129.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:135.36,137.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:138.37,140.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:141.46,143.3 1 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:161.81,162.19 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:165.2,165.70 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:168.2,168.49 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:162.19,164.3 1 5
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:165.70,167.3 1 385
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:174.62,180.9 4 816
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:190.2,190.48 1 816
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:196.2,196.21 1 816
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:180.9,181.44 1 393
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:187.3,187.29 1 393
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:181.44,183.4 1 61
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:183.9,186.4 2 332
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:190.48,195.3 4 84
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:210.41,212.2 1 414
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:215.60,216.19 1 887
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:216.19,219.11 3 414
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:223.3,223.16 1 414
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:229.3,230.24 2 412
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:233.3,243.17 6 412
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:247.3,250.89 2 130
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:251.3,251.17 1 130
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:258.3,258.49 1 130
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:219.11,221.4 1 408
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:223.16,227.4 3 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:230.24,232.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:243.17,246.4 2 282
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:250.89,250.129 1 130
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:251.17,256.4 3 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:258.49,262.4 3 6606
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:267.29,268.19 1 404
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:268.19,272.3 3 401
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:286.43,288.2 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:291.62,292.19 1 13
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:292.19,296.11 4 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:301.3,301.16 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:309.3,310.24 2 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:313.3,323.17 6 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:327.3,333.92 4 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:334.3,334.17 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:341.3,341.49 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:296.11,299.4 2 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:301.16,307.4 4 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:310.24,312.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:323.17,326.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:333.92,333.135 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:334.17,339.4 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:341.49,345.4 3 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:350.31,351.19 1 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:351.19,355.3 3 2
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:359.42,362.2 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:365.44,368.2 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:415.33,416.29 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:420.2,420.54 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:423.2,423.58 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:426.2,432.3 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:416.29,419.3 2 3
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:420.54,422.3 1 4
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:423.58,425.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:437.26,439.2 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:444.25,450.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:455.41,462.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:467.50,474.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:478.29,484.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:488.26,490.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:495.50,504.20 5 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:508.2,508.16 1 804
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:504.20,507.3 2 83
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:514.54,523.20 5 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:528.2,528.16 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:523.20,526.3 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:533.37,538.2 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:545.47,550.26 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:555.2,556.9 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:550.26,553.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:557.35,557.35 0 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:558.10,558.10 0 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:564.42,566.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:570.67,572.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/ethash.go:576.36,578.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:35.121,37.80 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:43.2,43.26 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:47.2,52.24 5 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:60.2,61.18 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:64.2,64.17 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:67.2,68.31 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:76.2,77.9 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:91.2,92.20 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:37.80,41.3 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:43.26,45.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:52.24,54.17 2 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:58.3,58.55 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:54.17,57.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:61.18,63.3 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:64.17,66.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:68.31,70.33 2 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:70.33,73.4 2 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:78.14,80.15 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:81.24,83.15 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:84.23,88.41 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:97.115,114.6 5 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:151.2,151.28 1 12
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:114.6,115.10 1 123
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:116.16,120.16 3 11
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:122.11,125.35 2 112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:130.4,131.54 2 112
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:146.4,146.11 1 111
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:125.35,128.5 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:131.54,138.12 4 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:144.5,144.17 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:139.42,140.93 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/ethash/sealer.go:141.18,142.94 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:42.73,45.55 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:51.2,51.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:54.2,54.81 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:45.55,47.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:47.8,49.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:51.19,53.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:58.72,60.19 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:63.2,63.81 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:60.19,62.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:67.79,70.55 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:76.2,76.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:79.2,80.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:83.2,83.31 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:70.55,72.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:72.8,74.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:76.19,78.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:80.16,82.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:87.78,89.19 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:92.2,93.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:96.2,96.31 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:89.19,91.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:93.16,95.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:99.57,105.22 6 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:116.2,116.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:105.22,110.3 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/api.go:110.8,115.3 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:193.55,215.2 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:217.55,219.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:222.86,225.49 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:229.2,229.35 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:232.2,236.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:239.2,243.20 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:225.49,227.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:229.35,231.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:236.16,238.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:275.62,278.21 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:282.2,296.3 6 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:278.21,280.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:301.69,303.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:306.40,306.59 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:309.103,311.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:316.137,320.12 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:331.2,331.23 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:320.12,321.34 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:321.34,324.11 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:325.17,326.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:327.24,327.24 0 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:334.137,336.11 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:339.2,340.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:343.2,343.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:336.11,338.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:340.16,342.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:350.128,351.22 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:354.2,354.26 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:357.2,358.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:368.2,369.57 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:374.2,374.98 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:377.2,377.64 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:381.2,381.37 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:384.2,384.47 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:388.2,389.38 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:392.2,392.58 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:396.2,396.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:400.2,400.35 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:404.2,404.77 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:408.2,408.68 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:351.22,353.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:354.26,356.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:358.16,359.76 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:363.3,363.57 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:359.76,361.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:363.57,365.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:369.57,371.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:374.98,376.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:377.64,379.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:381.37,383.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:384.47,386.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:389.38,391.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:392.58,394.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:396.41,398.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:400.35,402.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:404.77,406.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:415.137,418.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:422.2,423.22 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:428.2,428.95 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:431.2,431.65 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:435.2,435.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:444.2,445.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:449.2,451.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:455.2,456.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:459.2,460.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:464.2,464.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:418.17,420.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:423.22,425.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:425.8,427.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:428.95,430.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:431.65,433.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:435.32,437.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:445.16,447.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:451.16,453.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:456.16,458.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:460.16,462.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:467.124,470.45 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:473.2,474.60 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:492.2,493.49 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:498.2,502.19 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:506.2,506.28 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:513.2,513.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:470.45,472.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:474.60,476.49 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:481.3,481.17 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:484.3,484.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:487.3,488.52 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:476.49,478.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:478.9,480.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:481.17,483.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:484.40,486.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:488.52,490.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:493.49,494.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:494.40,496.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:502.19,505.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:506.28,508.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:508.17,510.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:518.79,519.40 1 5
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:522.2,522.40 1 4
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:525.2,525.40 1 4
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:528.2,528.40 1 4
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:519.40,521.3 1 1
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:522.40,524.3 1 6
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:525.40,527.3 1 8
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:531.98,535.16 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:538.2,538.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:535.16,537.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:541.52,543.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:545.60,546.28 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:551.2,551.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:546.28,547.16 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:547.16,549.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:554.99,557.9 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:558.16,559.60 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:560.16,562.55 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:563.10,564.28 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:568.35,568.61 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:570.81,571.33 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:574.2,575.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:578.2,578.15 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:571.33,573.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:575.16,577.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:581.128,584.22 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:593.2,594.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:598.2,598.27 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:601.2,604.33 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:611.2,612.24 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:615.2,615.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:618.2,618.47 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:621.2,621.57 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:584.22,591.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:594.16,597.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:598.27,600.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:604.33,606.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:609.3,609.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:606.17,608.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:612.24,614.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:615.32,617.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:618.47,620.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:625.131,631.18 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:683.2,683.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:686.2,687.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:690.2,693.52 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:699.2,699.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:631.18,633.39 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:639.3,639.48 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:647.3,647.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:664.3,665.23 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:679.3,680.45 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:633.39,635.9 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:639.48,640.78 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:640.78,643.10 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:647.18,649.63 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:652.4,653.38 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:656.4,657.43 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:660.4,661.9 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:649.63,651.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:653.38,655.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:657.43,659.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:665.23,668.65 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:671.4,671.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:668.65,670.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:672.9,675.21 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:675.21,677.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:683.38,685.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:687.16,689.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:693.52,694.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:697.3,697.88 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:694.41,696.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:704.84,705.29 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:708.2,708.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:705.29,707.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:713.84,715.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:723.126,726.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:730.2,731.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:736.2,737.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:740.2,741.22 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:746.2,749.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:754.2,756.32 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:759.2,760.38 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:763.2,763.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:776.2,776.26 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:793.2,793.59 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:809.2,809.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:726.17,728.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:731.16,733.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:737.16,739.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:741.22,743.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:743.8,745.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:749.16,750.54 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:750.54,752.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:756.32,758.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:760.38,762.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:763.41,765.33 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:771.3,771.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:765.33,766.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:766.20,768.10 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:771.13,774.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:776.26,777.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:777.42,778.25 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:778.25,781.48 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:781.48,783.36 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:783.36,785.7 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:793.59,795.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:800.3,801.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:804.3,804.37 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:795.17,797.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:801.17,803.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:804.37,807.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:812.128,816.19 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:819.2,819.15 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:822.2,823.21 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:830.2,831.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:834.2,834.24 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:816.19,818.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:819.15,821.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:823.21,824.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:824.20,826.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:826.9,828.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:831.16,833.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:839.81,847.16 5 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:850.2,850.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:871.2,872.19 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:876.2,879.37 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:882.2,884.60 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:922.2,930.45 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:933.2,933.12 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:847.16,849.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:850.32,855.47 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:861.3,861.25 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:869.3,869.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:855.47,856.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:856.42,858.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:861.25,863.36 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:863.36,865.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:865.10,867.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:872.19,874.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:879.37,881.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:884.60,885.61 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:906.3,906.50 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:911.3,911.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:914.3,914.29 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:885.61,888.50 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:893.4,893.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:896.4,896.31 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:888.50,890.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:890.10,892.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:893.18,895.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:896.31,899.44 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:902.5,902.68 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:899.44,901.6 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:906.50,907.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:907.41,909.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:911.42,913.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:914.29,916.18 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:919.4,919.34 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:916.18,918.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:930.45,932.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:936.108,941.16 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:944.2,945.23 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:948.2,950.23 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:953.2,955.12 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:941.16,943.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:945.23,947.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:950.23,952.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:960.225,967.52 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:984.2,988.56 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:967.52,969.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:972.3,972.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:969.17,971.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:972.40,974.18 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:977.4,977.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:974.18,976.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:977.18,979.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:993.73,999.2 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1003.114,1008.17 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1013.2,1013.90 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1017.2,1023.16 5 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1026.2,1027.56 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1041.2,1041.26 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1057.2,1057.9 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1063.2,1064.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1067.2,1069.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1072.2,1072.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1075.2,1075.36 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1008.17,1010.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1013.90,1015.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1023.16,1025.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1027.56,1029.33 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1035.3,1035.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1029.33,1030.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1030.19,1032.10 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1035.13,1037.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1041.26,1042.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1042.42,1043.24 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1043.24,1046.66 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1046.66,1048.36 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1048.36,1052.7 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1058.14,1059.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1060.10,1060.10 0 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1064.16,1066.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1069.16,1071.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1072.18,1074.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1081.104,1083.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1085.114,1087.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1090.2,1090.62 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1087.16,1089.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1095.60,1102.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1104.76,1106.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1108.79,1111.62 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1116.2,1116.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1120.2,1121.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1124.2,1128.20 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1111.62,1113.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1116.40,1118.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1121.16,1123.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1132.116,1133.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1137.2,1138.40 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1142.2,1142.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1133.32,1136.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1138.40,1140.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1145.122,1147.25 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1169.2,1172.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1147.25,1148.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1148.32,1150.31 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1161.4,1161.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1165.4,1165.33 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1150.31,1151.30 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1151.30,1152.30 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1157.6,1157.11 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1152.30,1154.7 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1154.12,1156.7 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1161.38,1162.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1175.93,1177.25 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1182.2,1184.16 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1177.25,1178.32 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1178.32,1180.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1187.39,1189.2 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1192.127,1193.22 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1196.2,1199.22 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1203.2,1203.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1193.22,1195.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1199.22,1202.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1207.90,1209.40 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1212.2,1212.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1209.40,1211.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1216.166,1217.69 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1221.2,1224.16 4 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1227.2,1227.18 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1217.69,1219.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1224.16,1226.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1230.172,1234.30 4 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1237.2,1237.16 1 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1248.2,1248.26 1 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1234.30,1236.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1237.16,1239.15 2 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1242.3,1242.34 1 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1239.15,1241.4 1 18
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1242.34,1246.4 3 54
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1252.64,1255.36 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1265.2,1265.19 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1255.36,1258.17 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1262.3,1262.52 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1258.17,1261.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1268.33,1269.9 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1270.17,1271.25 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1272.17,1273.33 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1274.10,1275.17 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1279.107,1282.22 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1291.2,1292.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1296.2,1296.27 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1299.2,1302.33 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1309.2,1310.45 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1313.2,1313.14 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1282.22,1289.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1292.16,1295.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1296.27,1298.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1302.33,1304.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1307.3,1307.40 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1304.17,1306.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1310.45,1312.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1316.126,1319.65 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1322.2,1323.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1326.2,1326.21 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1319.65,1321.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/XDPoS.go:1323.16,1325.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:62.138,72.33 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:75.2,75.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:72.33,74.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:79.126,81.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:84.2,85.51 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:88.2,91.18 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:81.16,83.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:85.51,87.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:95.51,97.16 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:100.2,100.60 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:97.16,99.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:104.37,115.32 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:118.2,118.39 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:121.2,121.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:124.2,126.12 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:115.32,117.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:118.39,120.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:121.38,123.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:131.75,134.2 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:137.70,139.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:143.2,143.37 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:149.2,149.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:139.38,141.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:143.37,146.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:146.8,148.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:153.72,156.9 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:160.2,160.34 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:164.2,164.21 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:170.2,170.13 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:156.9,158.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:160.34,162.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:164.21,167.3 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:167.8,169.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:175.70,177.23 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:181.2,181.38 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:186.2,186.46 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:190.2,192.33 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:282.2,285.18 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:177.23,179.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:181.38,182.67 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:182.67,184.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:186.46,188.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:192.33,195.33 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:200.3,200.64 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:204.3,205.17 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:217.3,220.35 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:231.3,232.10 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:240.3,240.44 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:249.3,249.78 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:195.33,198.4 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:200.64,202.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:205.17,207.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:220.35,221.64 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:221.64,227.10 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:233.52,234.20 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:235.52,236.21 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:237.11,238.30 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:240.44,247.4 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:249.78,250.23 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:273.4,273.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:279.4,279.39 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:250.23,252.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:252.10,256.66 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:260.5,260.42 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:256.66,258.6 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:260.42,261.49 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:261.49,269.7 3 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:273.41,274.49 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:274.49,277.6 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:289.50,291.32 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:294.2,294.36 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:301.2,301.16 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:291.32,293.3 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:294.36,295.41 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:295.41,296.55 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:296.55,298.5 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:305.70,307.57 2 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:310.2,310.58 1 0
+github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/snapshot.go:307.57,309.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:41.86,47.2 1 6
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:52.75,58.9 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:80.2,81.16 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:84.2,84.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:60.35,61.76 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:64.3,64.82 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:67.3,67.26 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:72.66,73.44 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:76.10,77.54 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:61.76,63.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:64.82,66.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:67.26,69.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:81.16,83.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:89.75,91.34 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:94.2,97.65 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:103.2,104.16 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:108.2,108.75 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:112.2,119.87 7 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:124.2,124.83 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:127.2,127.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:91.34,93.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:97.65,99.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:99.8,101.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:104.16,106.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:108.75,110.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:119.87,121.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:121.8,123.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:124.83,126.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:134.78,136.34 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:139.2,144.65 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:158.2,159.64 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:166.2,167.16 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:170.2,170.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:136.34,138.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:144.65,146.74 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:146.74,148.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:148.9,150.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:151.8,152.35 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:155.3,155.28 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:152.35,154.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:159.64,160.35 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:163.3,163.30 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:160.35,162.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:167.16,169.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:176.69,183.25 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:186.2,186.25 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:191.2,191.45 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:199.2,199.24 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:204.2,205.16 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:208.2,208.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:183.25,185.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:186.25,188.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:191.45,193.74 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:193.74,195.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:195.9,197.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:199.24,201.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:205.16,207.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:212.70,213.33 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:218.2,218.62 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:213.33,217.3 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:223.76,230.16 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:233.2,233.16 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:240.2,240.16 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:249.2,249.30 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:261.2,264.34 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:270.2,270.26 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:230.16,232.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:233.16,234.34 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:234.34,236.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:236.9,238.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:240.16,241.34 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:241.34,243.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:243.9,245.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:249.30,251.17 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:254.3,255.17 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:258.3,258.15 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:251.17,253.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:255.17,257.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:264.34,265.37 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:268.3,268.26 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:265.37,267.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:280.69,284.16 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:287.2,294.22 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:304.2,305.27 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:334.2,334.11 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:339.2,339.54 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:343.2,343.17 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:284.16,286.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:294.22,297.3 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:297.8,301.3 3 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:305.27,310.28 5 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:329.3,329.27 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:311.12,312.21 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:324.18,325.48 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:326.11,327.39 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:312.21,316.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:316.10,318.19 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:318.19,320.6 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:320.11,322.6 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:334.11,336.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:336.8,338.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:339.54,342.3 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:346.56,348.2 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:352.51,354.16 2 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:357.2,357.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/bridge.go:354.16,356.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:76.43,78.28 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:81.2,81.25 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:84.2,84.27 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:88.2,96.58 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:99.2,99.53 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:102.2,102.21 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:78.28,80.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:81.25,83.3 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:84.27,86.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:96.58,98.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:99.53,101.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:107.48,121.74 9 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:124.2,124.64 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:127.2,127.69 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:130.2,130.68 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:134.2,135.16 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:138.2,139.24 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:154.2,154.46 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:161.2,161.23 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:192.2,193.16 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:196.2,196.39 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:202.2,202.31 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:212.2,212.23 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:221.2,221.12 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:121.74,123.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:124.64,126.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:127.69,129.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:130.68,132.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:135.16,137.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:139.24,140.20 1 66
+github.com/XinFinOrg/XDPoSChain/console/console.go:143.3,143.43 1 60
+github.com/XinFinOrg/XDPoSChain/console/console.go:140.20,141.12 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:143.43,145.73 1 60
+github.com/XinFinOrg/XDPoSChain/console/console.go:148.4,148.58 1 60
+github.com/XinFinOrg/XDPoSChain/console/console.go:145.73,147.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:149.9,149.81 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:149.81,152.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:154.46,156.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:161.23,164.17 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:172.3,172.43 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:164.17,166.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:172.43,173.81 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:176.4,176.87 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:179.4,179.81 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:182.4,182.69 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:185.4,188.32 4 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:173.81,175.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:176.87,178.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:179.81,181.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:182.69,184.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:193.16,195.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:196.39,200.3 3 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:202.31,203.43 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:203.43,205.44 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:208.4,208.46 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:205.44,207.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:212.23,213.62 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:219.3,219.51 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:213.62,215.4 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:215.9,218.4 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:224.34,227.46 3 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:227.46,229.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:229.8,231.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:236.68,238.45 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:241.2,242.21 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:238.45,240.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:247.86,249.32 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:254.2,255.27 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:269.2,269.75 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:249.32,251.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:255.27,257.117 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:261.3,261.50 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:266.3,267.8 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:257.117,258.12 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:261.50,263.12 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:274.29,284.58 3 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:292.2,292.25 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:284.58,286.34 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:289.3,290.67 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:286.34,288.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:297.52,298.15 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:303.2,303.46 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:298.15,299.31 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:299.31,301.4 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:308.33,316.12 2 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:335.2,339.6 3 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:316.12,317.7 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:317.7,320.18 2 2
+github.com/XinFinOrg/XDPoSChain/console/console.go:331.4,331.21 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:320.18,322.38 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:327.5,328.11 2 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:322.38,325.14 3 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:339.6,342.10 2 2
+github.com/XinFinOrg/XDPoSChain/console/console.go:343.16,346.10 2 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:348.32,350.55 1 2
+github.com/XinFinOrg/XDPoSChain/console/console.go:353.4,353.40 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:357.4,360.20 3 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:366.4,366.20 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:350.55,352.5 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:353.40,354.13 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:360.20,362.5 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:362.10,364.5 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:366.20,367.80 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:375.5,376.15 2 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:367.80,368.108 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:368.108,370.28 2 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:370.28,372.8 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:384.37,392.26 2 24
+github.com/XinFinOrg/XDPoSChain/console/console.go:422.2,422.16 1 24
+github.com/XinFinOrg/XDPoSChain/console/console.go:392.26,393.12 1 527
+github.com/XinFinOrg/XDPoSChain/console/console.go:394.13,396.32 1 8
+github.com/XinFinOrg/XDPoSChain/console/console.go:399.18,400.52 1 28
+github.com/XinFinOrg/XDPoSChain/console/console.go:406.4,406.23 1 28
+github.com/XinFinOrg/XDPoSChain/console/console.go:407.17,408.17 1 34
+github.com/XinFinOrg/XDPoSChain/console/console.go:411.4,411.23 1 34
+github.com/XinFinOrg/XDPoSChain/console/console.go:412.17,413.17 1 19
+github.com/XinFinOrg/XDPoSChain/console/console.go:416.4,416.23 1 19
+github.com/XinFinOrg/XDPoSChain/console/console.go:417.11,418.23 1 438
+github.com/XinFinOrg/XDPoSChain/console/console.go:396.32,398.5 1 4
+github.com/XinFinOrg/XDPoSChain/console/console.go:400.52,402.5 1 11
+github.com/XinFinOrg/XDPoSChain/console/console.go:402.10,402.40 1 17
+github.com/XinFinOrg/XDPoSChain/console/console.go:402.40,405.5 2 13
+github.com/XinFinOrg/XDPoSChain/console/console.go:408.17,410.5 1 24
+github.com/XinFinOrg/XDPoSChain/console/console.go:413.17,415.5 1 17
+github.com/XinFinOrg/XDPoSChain/console/console.go:426.46,428.2 1 1
+github.com/XinFinOrg/XDPoSChain/console/console.go:431.45,432.98 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:435.2,435.51 1 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:438.2,439.12 2 6
+github.com/XinFinOrg/XDPoSChain/console/console.go:432.98,434.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/console.go:435.51,437.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:82.46,90.46 5 1
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:99.2,102.10 4 1
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:90.46,92.3 1 1
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:92.8,98.3 4 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:107.71,108.17 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:119.2,119.31 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:108.17,111.3 2 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:111.8,118.3 3 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:125.85,126.17 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:131.2,131.15 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:136.2,139.20 4 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:126.17,130.3 3 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:131.15,134.3 2 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:144.71,146.57 2 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:149.2,149.19 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:146.57,148.3 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:154.57,156.2 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:159.58,161.2 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:164.43,166.2 1 0
+github.com/XinFinOrg/XDPoSChain/console/prompter.go:170.70,172.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:63.176,66.29 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:164.2,164.12 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:66.29,74.53 4 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:87.3,90.17 4 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:95.3,96.17 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:102.3,109.114 5 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:135.3,135.117 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:74.53,75.72 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:75.72,78.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:78.10,80.55 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:80.55,82.6 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:90.17,93.4 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:96.17,99.4 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:109.114,114.18 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:118.4,119.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:124.4,125.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:131.4,131.52 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:114.18,117.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:119.18,122.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:125.18,128.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:135.117,137.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:142.4,143.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:147.4,148.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:153.4,154.18 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:160.4,160.36 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:137.18,140.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:143.18,146.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:148.18,151.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:154.18,157.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:168.125,175.2 5 30
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:178.141,192.33 10 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:196.2,198.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:192.33,195.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:202.123,208.2 4 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:211.105,213.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:216.141,218.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:222.2,224.16 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:228.2,228.19 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:218.16,221.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:224.16,227.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:232.106,234.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:237.2,239.16 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:242.2,243.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:247.2,247.64 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:234.16,236.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:239.16,241.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:243.16,245.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:251.80,256.31 5 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:259.2,260.48 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:273.2,273.24 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:256.31,258.3 1 11
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:260.48,262.23 2 150
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:265.3,270.23 6 150
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:262.23,264.4 1 2
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:277.50,279.34 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:285.2,285.23 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:279.34,283.3 2 150
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:289.69,291.16 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:295.2,295.61 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:291.16,293.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:299.97,301.22 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:316.2,316.20 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:301.22,302.34 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:302.34,305.28 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:305.28,307.19 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:311.5,311.30 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:307.19,310.6 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:320.174,330.78 8 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:352.2,355.54 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:385.2,387.21 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:330.78,334.10 4 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:345.3,346.26 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:334.10,338.51 4 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:338.51,341.5 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:341.10,343.5 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:346.26,350.4 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:355.54,356.86 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:356.86,359.22 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:359.22,361.44 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:372.5,372.35 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:361.44,362.33 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:362.33,363.29 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:363.29,364.43 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:367.8,367.13 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:364.43,366.9 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:372.35,374.15 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:379.6,379.20 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:374.15,376.7 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:376.12,378.7 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:391.149,394.21 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:405.2,406.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:410.2,412.27 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:394.21,395.37 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:395.37,403.4 5 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:406.16,409.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:416.97,419.2 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:421.192,423.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:426.2,426.21 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:423.16,425.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:429.193,438.21 7 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:468.2,473.16 5 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:477.2,479.22 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:438.21,444.35 5 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:452.3,452.49 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:444.35,445.87 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:448.4,450.34 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:445.87,446.13 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:452.49,453.41 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:453.41,455.50 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:455.50,458.31 3 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:458.31,460.7 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:460.12,462.7 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:473.16,476.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:483.59,485.19 2 3
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:490.2,490.10 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:485.19,488.3 2 310
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:494.37,498.36 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:506.2,506.17 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:498.36,504.3 5 9
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:510.46,515.16 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:522.2,524.62 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:529.2,533.54 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:515.16,518.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:524.62,527.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:537.52,541.16 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:548.2,548.37 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:552.2,560.38 5 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:541.16,544.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:548.37,551.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:564.35,567.19 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:571.2,571.10 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:567.19,570.3 2 32
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:575.35,576.51 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:576.51,578.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/utils.go:578.8,580.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:30.143,32.16 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:36.2,42.8 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:32.16,34.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:45.155,47.16 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:51.2,52.16 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:56.2,56.42 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:47.16,49.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/blocksigner.go:52.16,54.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:34.41,36.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:38.44,40.15 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:43.2,43.35 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:40.15,42.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:46.97,48.15 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:51.2,51.38 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:48.15,50.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:54.66,56.15 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:59.2,59.24 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:56.15,58.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:62.70,64.15 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:67.2,67.27 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/api.go:64.15,66.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:78.37,80.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:112.41,114.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:117.135,122.16 4 7
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:125.2,144.40 4 7
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:148.2,148.8 1 7
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:122.16,124.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:144.40,147.3 2 6
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:151.52,153.16 2 6
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:153.16,155.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:155.8,157.3 1 6
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:161.126,164.16 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:167.2,170.16 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:173.2,173.18 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:176.2,178.8 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:164.16,166.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:170.16,172.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:173.18,175.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:190.58,193.16 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:196.2,197.9 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:200.2,201.36 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:207.2,207.12 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:193.16,195.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:197.9,199.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:201.36,203.10 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:203.10,205.4 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:211.55,218.36 2 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:221.2,221.27 1 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:218.36,220.3 1 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:226.44,228.16 2 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:231.2,233.55 2 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:228.16,230.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:237.32,240.22 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:240.22,243.3 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:248.100,252.24 3 27
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:255.2,255.34 1 26
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:283.2,283.27 1 26
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:290.2,290.8 1 26
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:252.24,254.3 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:255.34,257.3 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:257.8,260.13 3 25
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:264.3,268.17 4 25
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:260.13,263.4 2 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:268.17,277.4 3 25
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:283.27,284.43 1 11
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:284.43,287.4 2 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:294.69,296.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:299.73,301.25 2 35
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:304.2,308.32 5 35
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:301.25,303.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:312.44,316.2 3 12
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:319.48,321.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:324.50,326.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:329.66,333.2 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:337.66,343.16 5 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:348.2,350.29 3 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:343.16,346.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:356.89,362.2 5 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:366.61,367.22 1 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:372.2,372.121 1 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:376.2,380.12 4 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:367.22,370.3 2 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:372.121,374.3 1 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:380.12,381.7 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:381.7,382.11 1 7
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:383.16,384.11 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:385.20,387.42 2 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:394.5,394.23 1 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:387.42,390.20 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:390.20,392.7 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:407.72,409.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:412.66,414.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:417.85,419.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:422.29,422.30 0 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:425.37,427.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:448.162,449.19 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:452.2,453.16 2 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:456.2,474.8 7 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:449.19,451.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:453.16,455.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:477.36,479.2 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:482.27,485.22 3 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:485.22,488.3 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:492.54,493.24 1 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:498.2,498.8 1 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:493.24,497.3 3 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:503.79,508.2 4 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:513.57,514.22 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:519.2,519.97 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:523.2,527.12 4 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:514.22,517.3 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:519.97,521.3 1 2
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:527.12,528.7 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:528.7,529.11 1 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:530.16,531.11 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:532.20,534.71 2 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:540.5,540.23 1 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:534.71,536.20 2 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:536.20,538.7 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:548.68,555.24 5 13
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:566.2,568.16 3 13
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:580.2,580.20 1 13
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:555.24,558.17 2 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:561.3,561.14 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:558.17,560.4 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:562.8,564.3 1 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:568.16,571.30 2 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:577.3,577.96 1 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:571.30,573.42 2 4
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:573.42,575.5 1 3
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:584.126,586.16 2 13
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:590.2,590.37 1 13
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:593.2,593.31 1 12
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:597.2,598.16 2 11
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:605.2,606.16 2 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:609.2,609.79 1 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:612.2,612.20 1 10
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:586.16,588.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:590.37,592.3 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:593.31,595.3 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:598.16,600.25 2 11
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:600.25,602.4 1 1
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:606.16,608.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:609.79,611.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:616.50,621.2 4 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:624.79,627.16 3 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:630.2,630.29 1 5
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:627.16,629.3 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:635.96,637.16 2 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:640.2,640.78 1 0
+github.com/XinFinOrg/XDPoSChain/contracts/chequebook/cheque.go:637.16,639.3 1 0
diff --git a/crypto/blake2b/blake2b.go b/crypto/blake2b/blake2b.go
new file mode 100644
index 0000000000..5da50cab6f
--- /dev/null
+++ b/crypto/blake2b/blake2b.go
@@ -0,0 +1,319 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693
+// and the extendable output function (XOF) BLAKE2Xb.
+//
+// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf
+// and for BLAKE2Xb see https://blake2.net/blake2x.pdf
+//
+// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512).
+// If you need a secret-key MAC (message authentication code), use the New512
+// function with a non-nil key.
+//
+// BLAKE2X is a construction to compute hash values larger than 64 bytes. It
+// can produce hash values between 0 and 4 GiB.
+package blake2b
+
+import (
+ "encoding/binary"
+ "errors"
+ "hash"
+)
+
+const (
+ // The blocksize of BLAKE2b in bytes.
+ BlockSize = 128
+ // The hash size of BLAKE2b-512 in bytes.
+ Size = 64
+ // The hash size of BLAKE2b-384 in bytes.
+ Size384 = 48
+ // The hash size of BLAKE2b-256 in bytes.
+ Size256 = 32
+)
+
+var (
+ useAVX2 bool
+ useAVX bool
+ useSSE4 bool
+)
+
+var (
+ errKeySize = errors.New("blake2b: invalid key size")
+ errHashSize = errors.New("blake2b: invalid hash size")
+)
+
+var iv = [8]uint64{
+ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+ 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
+}
+
+// Sum512 returns the BLAKE2b-512 checksum of the data.
+func Sum512(data []byte) [Size]byte {
+ var sum [Size]byte
+ checkSum(&sum, Size, data)
+ return sum
+}
+
+// Sum384 returns the BLAKE2b-384 checksum of the data.
+func Sum384(data []byte) [Size384]byte {
+ var sum [Size]byte
+ var sum384 [Size384]byte
+ checkSum(&sum, Size384, data)
+ copy(sum384[:], sum[:Size384])
+ return sum384
+}
+
+// Sum256 returns the BLAKE2b-256 checksum of the data.
+func Sum256(data []byte) [Size256]byte {
+ var sum [Size]byte
+ var sum256 [Size256]byte
+ checkSum(&sum, Size256, data)
+ copy(sum256[:], sum[:Size256])
+ return sum256
+}
+
+// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
+
+// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }
+
+// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
+
+// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
+// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+// The hash size can be a value between 1 and 64 but it is highly recommended to use
+// values equal or greater than:
+// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).
+// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).
+// When the key is nil, the returned hash.Hash implements BinaryMarshaler
+// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
+func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }
+
+// F is a compression function for BLAKE2b. It takes as an argument the state
+// vector `h`, message block vector `m`, offset counter `t`, final block indicator
+// flag `f`, and number of rounds `rounds`. The state vector provided as the first
+// parameter is modified by the function.
+func F(h *[8]uint64, m [16]uint64, c [2]uint64, final bool, rounds uint32) {
+ var flag uint64
+ if final {
+ flag = 0xFFFFFFFFFFFFFFFF
+ }
+ f(h, &m, c[0], c[1], flag, uint64(rounds))
+}
+
+func newDigest(hashSize int, key []byte) (*digest, error) {
+ if hashSize < 1 || hashSize > Size {
+ return nil, errHashSize
+ }
+ if len(key) > Size {
+ return nil, errKeySize
+ }
+ d := &digest{
+ size: hashSize,
+ keyLen: len(key),
+ }
+ copy(d.key[:], key)
+ d.Reset()
+ return d, nil
+}
+
+func checkSum(sum *[Size]byte, hashSize int, data []byte) {
+ h := iv
+ h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)
+ var c [2]uint64
+
+ if length := len(data); length > BlockSize {
+ n := length &^ (BlockSize - 1)
+ if length == n {
+ n -= BlockSize
+ }
+ hashBlocks(&h, &c, 0, data[:n])
+ data = data[n:]
+ }
+
+ var block [BlockSize]byte
+ offset := copy(block[:], data)
+ remaining := uint64(BlockSize - offset)
+ if c[0] < remaining {
+ c[1]--
+ }
+ c[0] -= remaining
+
+ hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+ for i, v := range h[:(hashSize+7)/8] {
+ binary.LittleEndian.PutUint64(sum[8*i:], v)
+ }
+}
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+ var m [16]uint64
+ c0, c1 := c[0], c[1]
+
+ for i := 0; i < len(blocks); {
+ c0 += BlockSize
+ if c0 < BlockSize {
+ c1++
+ }
+ for j := range m {
+ m[j] = binary.LittleEndian.Uint64(blocks[i:])
+ i += 8
+ }
+ f(h, &m, c0, c1, flag, 12)
+ }
+ c[0], c[1] = c0, c1
+}
+
+type digest struct {
+ h [8]uint64
+ c [2]uint64
+ size int
+ block [BlockSize]byte
+ offset int
+
+ key [BlockSize]byte
+ keyLen int
+}
+
+const (
+ magic = "b2b"
+ marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+ if d.keyLen != 0 {
+ return nil, errors.New("crypto/blake2b: cannot marshal MACs")
+ }
+ b := make([]byte, 0, marshaledSize)
+ b = append(b, magic...)
+ for i := 0; i < 8; i++ {
+ b = appendUint64(b, d.h[i])
+ }
+ b = appendUint64(b, d.c[0])
+ b = appendUint64(b, d.c[1])
+ // Maximum value for size is 64
+ b = append(b, byte(d.size))
+ b = append(b, d.block[:]...)
+ b = append(b, byte(d.offset))
+ return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+ if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+ return errors.New("crypto/blake2b: invalid hash state identifier")
+ }
+ if len(b) != marshaledSize {
+ return errors.New("crypto/blake2b: invalid hash state size")
+ }
+ b = b[len(magic):]
+ for i := 0; i < 8; i++ {
+ b, d.h[i] = consumeUint64(b)
+ }
+ b, d.c[0] = consumeUint64(b)
+ b, d.c[1] = consumeUint64(b)
+ d.size = int(b[0])
+ b = b[1:]
+ copy(d.block[:], b[:BlockSize])
+ b = b[BlockSize:]
+ d.offset = int(b[0])
+ return nil
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Size() int { return d.size }
+
+func (d *digest) Reset() {
+ d.h = iv
+ d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)
+ d.offset, d.c[0], d.c[1] = 0, 0, 0
+ if d.keyLen > 0 {
+ d.block = d.key
+ d.offset = BlockSize
+ }
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+ n = len(p)
+
+ if d.offset > 0 {
+ remaining := BlockSize - d.offset
+ if n <= remaining {
+ d.offset += copy(d.block[d.offset:], p)
+ return
+ }
+ copy(d.block[d.offset:], p[:remaining])
+ hashBlocks(&d.h, &d.c, 0, d.block[:])
+ d.offset = 0
+ p = p[remaining:]
+ }
+
+ if length := len(p); length > BlockSize {
+ nn := length &^ (BlockSize - 1)
+ if length == nn {
+ nn -= BlockSize
+ }
+ hashBlocks(&d.h, &d.c, 0, p[:nn])
+ p = p[nn:]
+ }
+
+ if len(p) > 0 {
+ d.offset += copy(d.block[:], p)
+ }
+
+ return
+}
+
+func (d *digest) Sum(sum []byte) []byte {
+ var hash [Size]byte
+ d.finalize(&hash)
+ return append(sum, hash[:d.size]...)
+}
+
+func (d *digest) finalize(hash *[Size]byte) {
+ var block [BlockSize]byte
+ copy(block[:], d.block[:d.offset])
+ remaining := uint64(BlockSize - d.offset)
+
+ c := d.c
+ if c[0] < remaining {
+ c[1]--
+ }
+ c[0] -= remaining
+
+ h := d.h
+ hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+ for i, v := range h {
+ binary.LittleEndian.PutUint64(hash[8*i:], v)
+ }
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+ var a [8]byte
+ binary.BigEndian.PutUint64(a[:], x)
+ return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+ var a [4]byte
+ binary.BigEndian.PutUint32(a[:], x)
+ return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+ x := binary.BigEndian.Uint64(b)
+ return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+ x := binary.BigEndian.Uint32(b)
+ return b[4:], x
+}
diff --git a/crypto/blake2b/blake2bAVX2_amd64.go b/crypto/blake2b/blake2bAVX2_amd64.go
new file mode 100644
index 0000000000..0d52b18699
--- /dev/null
+++ b/crypto/blake2b/blake2bAVX2_amd64.go
@@ -0,0 +1,37 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7,amd64,!gccgo,!appengine
+
+package blake2b
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+ useAVX2 = cpu.X86.HasAVX2
+ useAVX = cpu.X86.HasAVX
+ useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func fAVX2(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+
+//go:noescape
+func fAVX(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+
+//go:noescape
+func fSSE4(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+
+func f(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
+ switch {
+ case useAVX2:
+ fAVX2(h, m, c0, c1, flag, rounds)
+ case useAVX:
+ fAVX(h, m, c0, c1, flag, rounds)
+ case useSSE4:
+ fSSE4(h, m, c0, c1, flag, rounds)
+ default:
+ fGeneric(h, m, c0, c1, flag, rounds)
+ }
+}
diff --git a/crypto/blake2b/blake2bAVX2_amd64.s b/crypto/blake2b/blake2bAVX2_amd64.s
new file mode 100644
index 0000000000..4998af37dd
--- /dev/null
+++ b/crypto/blake2b/blake2bAVX2_amd64.s
@@ -0,0 +1,717 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7,amd64,!gccgo,!appengine
+
+#include "textflag.h"
+
+DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16
+
+#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39
+#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93
+#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e
+#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93
+#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39
+
+#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \
+ VPADDQ m0, Y0, Y0; \
+ VPADDQ Y1, Y0, Y0; \
+ VPXOR Y0, Y3, Y3; \
+ VPSHUFD $-79, Y3, Y3; \
+ VPADDQ Y3, Y2, Y2; \
+ VPXOR Y2, Y1, Y1; \
+ VPSHUFB c40, Y1, Y1; \
+ VPADDQ m1, Y0, Y0; \
+ VPADDQ Y1, Y0, Y0; \
+ VPXOR Y0, Y3, Y3; \
+ VPSHUFB c48, Y3, Y3; \
+ VPADDQ Y3, Y2, Y2; \
+ VPXOR Y2, Y1, Y1; \
+ VPADDQ Y1, Y1, t; \
+ VPSRLQ $63, Y1, Y1; \
+ VPXOR t, Y1, Y1; \
+ VPERMQ_0x39_Y1_Y1; \
+ VPERMQ_0x4E_Y2_Y2; \
+ VPERMQ_0x93_Y3_Y3; \
+ VPADDQ m2, Y0, Y0; \
+ VPADDQ Y1, Y0, Y0; \
+ VPXOR Y0, Y3, Y3; \
+ VPSHUFD $-79, Y3, Y3; \
+ VPADDQ Y3, Y2, Y2; \
+ VPXOR Y2, Y1, Y1; \
+ VPSHUFB c40, Y1, Y1; \
+ VPADDQ m3, Y0, Y0; \
+ VPADDQ Y1, Y0, Y0; \
+ VPXOR Y0, Y3, Y3; \
+ VPSHUFB c48, Y3, Y3; \
+ VPADDQ Y3, Y2, Y2; \
+ VPXOR Y2, Y1, Y1; \
+ VPADDQ Y1, Y1, t; \
+ VPSRLQ $63, Y1, Y1; \
+ VPXOR t, Y1, Y1; \
+ VPERMQ_0x39_Y3_Y3; \
+ VPERMQ_0x4E_Y2_Y2; \
+ VPERMQ_0x93_Y1_Y1
+
+#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E
+#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26
+#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E
+#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36
+#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E
+
+#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n
+#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n
+#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n
+#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n
+#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n
+
+#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01
+#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01
+#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01
+#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01
+#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01
+
+#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01
+
+#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8
+#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01
+
+// load msg: Y12 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \
+ VMOVQ_SI_X12(i0*8); \
+ VMOVQ_SI_X11(i2*8); \
+ VPINSRQ_1_SI_X12(i1*8); \
+ VPINSRQ_1_SI_X11(i3*8); \
+ VINSERTI128 $1, X11, Y12, Y12
+
+// load msg: Y13 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \
+ VMOVQ_SI_X13(i0*8); \
+ VMOVQ_SI_X11(i2*8); \
+ VPINSRQ_1_SI_X13(i1*8); \
+ VPINSRQ_1_SI_X11(i3*8); \
+ VINSERTI128 $1, X11, Y13, Y13
+
+// load msg: Y14 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \
+ VMOVQ_SI_X14(i0*8); \
+ VMOVQ_SI_X11(i2*8); \
+ VPINSRQ_1_SI_X14(i1*8); \
+ VPINSRQ_1_SI_X11(i3*8); \
+ VINSERTI128 $1, X11, Y14, Y14
+
+// load msg: Y15 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \
+ VMOVQ_SI_X15(i0*8); \
+ VMOVQ_SI_X11(i2*8); \
+ VPINSRQ_1_SI_X15(i1*8); \
+ VPINSRQ_1_SI_X11(i3*8); \
+ VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \
+ VMOVQ_SI_X12_0; \
+ VMOVQ_SI_X11(4*8); \
+ VPINSRQ_1_SI_X12(2*8); \
+ VPINSRQ_1_SI_X11(6*8); \
+ VINSERTI128 $1, X11, Y12, Y12; \
+ LOAD_MSG_AVX2_Y13(1, 3, 5, 7); \
+ LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \
+ LOAD_MSG_AVX2_Y15(9, 11, 13, 15)
+
+#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \
+ LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \
+ LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \
+ VMOVQ_SI_X11(11*8); \
+ VPSHUFD $0x4E, 0*8(SI), X14; \
+ VPINSRQ_1_SI_X11(5*8); \
+ VINSERTI128 $1, X11, Y14, Y14; \
+ LOAD_MSG_AVX2_Y15(12, 2, 7, 3)
+
+#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \
+ VMOVQ_SI_X11(5*8); \
+ VMOVDQU 11*8(SI), X12; \
+ VPINSRQ_1_SI_X11(15*8); \
+ VINSERTI128 $1, X11, Y12, Y12; \
+ VMOVQ_SI_X13(8*8); \
+ VMOVQ_SI_X11(2*8); \
+ VPINSRQ_1_SI_X13_0; \
+ VPINSRQ_1_SI_X11(13*8); \
+ VINSERTI128 $1, X11, Y13, Y13; \
+ LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \
+ LOAD_MSG_AVX2_Y15(14, 6, 1, 4)
+
+#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \
+ LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \
+ LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \
+ LOAD_MSG_AVX2_Y14(2, 5, 4, 15); \
+ VMOVQ_SI_X15(6*8); \
+ VMOVQ_SI_X11_0; \
+ VPINSRQ_1_SI_X15(10*8); \
+ VPINSRQ_1_SI_X11(8*8); \
+ VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \
+ LOAD_MSG_AVX2_Y12(9, 5, 2, 10); \
+ VMOVQ_SI_X13_0; \
+ VMOVQ_SI_X11(4*8); \
+ VPINSRQ_1_SI_X13(7*8); \
+ VPINSRQ_1_SI_X11(15*8); \
+ VINSERTI128 $1, X11, Y13, Y13; \
+ LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \
+ LOAD_MSG_AVX2_Y15(1, 12, 8, 13)
+
+#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \
+ VMOVQ_SI_X12(2*8); \
+ VMOVQ_SI_X11_0; \
+ VPINSRQ_1_SI_X12(6*8); \
+ VPINSRQ_1_SI_X11(8*8); \
+ VINSERTI128 $1, X11, Y12, Y12; \
+ LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \
+ LOAD_MSG_AVX2_Y14(4, 7, 15, 1); \
+ LOAD_MSG_AVX2_Y15(13, 5, 14, 9)
+
+#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \
+ LOAD_MSG_AVX2_Y12(12, 1, 14, 4); \
+ LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \
+ VMOVQ_SI_X14_0; \
+ VPSHUFD $0x4E, 8*8(SI), X11; \
+ VPINSRQ_1_SI_X14(6*8); \
+ VINSERTI128 $1, X11, Y14, Y14; \
+ LOAD_MSG_AVX2_Y15(7, 3, 2, 11)
+
+#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \
+ LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \
+ LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \
+ LOAD_MSG_AVX2_Y14(5, 15, 8, 2); \
+ VMOVQ_SI_X15_0; \
+ VMOVQ_SI_X11(6*8); \
+ VPINSRQ_1_SI_X15(4*8); \
+ VPINSRQ_1_SI_X11(10*8); \
+ VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \
+ VMOVQ_SI_X12(6*8); \
+ VMOVQ_SI_X11(11*8); \
+ VPINSRQ_1_SI_X12(14*8); \
+ VPINSRQ_1_SI_X11_0; \
+ VINSERTI128 $1, X11, Y12, Y12; \
+ LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \
+ VMOVQ_SI_X11(1*8); \
+ VMOVDQU 12*8(SI), X14; \
+ VPINSRQ_1_SI_X11(10*8); \
+ VINSERTI128 $1, X11, Y14, Y14; \
+ VMOVQ_SI_X15(2*8); \
+ VMOVDQU 4*8(SI), X11; \
+ VPINSRQ_1_SI_X15(7*8); \
+ VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \
+ LOAD_MSG_AVX2_Y12(10, 8, 7, 1); \
+ VMOVQ_SI_X13(2*8); \
+ VPSHUFD $0x4E, 5*8(SI), X11; \
+ VPINSRQ_1_SI_X13(4*8); \
+ VINSERTI128 $1, X11, Y13, Y13; \
+ LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \
+ VMOVQ_SI_X15(11*8); \
+ VMOVQ_SI_X11(12*8); \
+ VPINSRQ_1_SI_X15(14*8); \
+ VPINSRQ_1_SI_X11_0; \
+ VINSERTI128 $1, X11, Y15, Y15
+
+// func fAVX2(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+TEXT ·fAVX2(SB), 4, $64-48 // frame size = 32 + 32 byte alignment
+ MOVQ h+0(FP), AX
+ MOVQ m+8(FP), SI
+ MOVQ c0+16(FP), R8
+ MOVQ c1+24(FP), R9
+ MOVQ flag+32(FP), CX
+ MOVQ rounds+40(FP), BX
+
+ MOVQ SP, DX
+ MOVQ SP, R10
+ ADDQ $31, R10
+ ANDQ $~31, R10
+ MOVQ R10, SP
+
+ MOVQ CX, 16(SP)
+ XORQ CX, CX
+ MOVQ CX, 24(SP)
+
+ VMOVDQU ·AVX2_c40<>(SB), Y4
+ VMOVDQU ·AVX2_c48<>(SB), Y5
+
+ VMOVDQU 0(AX), Y8
+ VMOVDQU 32(AX), Y9
+ VMOVDQU ·AVX2_iv0<>(SB), Y6
+ VMOVDQU ·AVX2_iv1<>(SB), Y7
+
+ MOVQ R8, 0(SP)
+ MOVQ R9, 8(SP)
+
+ VMOVDQA Y8, Y0
+ VMOVDQA Y9, Y1
+ VMOVDQA Y6, Y2
+ VPXOR 0(SP), Y7, Y3
+
+loop:
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0()
+ ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+ JMP loop
+
+done:
+ VPXOR Y0, Y8, Y8
+ VPXOR Y1, Y9, Y9
+ VPXOR Y2, Y8, Y8
+ VPXOR Y3, Y9, Y9
+
+ VMOVDQU Y8, 0(AX)
+ VMOVDQU Y9, 32(AX)
+ VZEROUPPER
+
+ MOVQ DX, SP
+ RET
+
+#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA
+#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB
+#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF
+#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD
+#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE
+
+#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF
+#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF
+
+#define SHUFFLE_AVX() \
+ VMOVDQA X6, X13; \
+ VMOVDQA X2, X14; \
+ VMOVDQA X4, X6; \
+ VPUNPCKLQDQ_X13_X13_X15; \
+ VMOVDQA X5, X4; \
+ VMOVDQA X6, X5; \
+ VPUNPCKHQDQ_X15_X7_X6; \
+ VPUNPCKLQDQ_X7_X7_X15; \
+ VPUNPCKHQDQ_X15_X13_X7; \
+ VPUNPCKLQDQ_X3_X3_X15; \
+ VPUNPCKHQDQ_X15_X2_X2; \
+ VPUNPCKLQDQ_X14_X14_X15; \
+ VPUNPCKHQDQ_X15_X3_X3; \
+
+#define SHUFFLE_AVX_INV() \
+ VMOVDQA X2, X13; \
+ VMOVDQA X4, X14; \
+ VPUNPCKLQDQ_X2_X2_X15; \
+ VMOVDQA X5, X4; \
+ VPUNPCKHQDQ_X15_X3_X2; \
+ VMOVDQA X14, X5; \
+ VPUNPCKLQDQ_X3_X3_X15; \
+ VMOVDQA X6, X14; \
+ VPUNPCKHQDQ_X15_X13_X3; \
+ VPUNPCKLQDQ_X7_X7_X15; \
+ VPUNPCKHQDQ_X15_X6_X6; \
+ VPUNPCKLQDQ_X14_X14_X15; \
+ VPUNPCKHQDQ_X15_X7_X7; \
+
+#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+ VPADDQ m0, v0, v0; \
+ VPADDQ v2, v0, v0; \
+ VPADDQ m1, v1, v1; \
+ VPADDQ v3, v1, v1; \
+ VPXOR v0, v6, v6; \
+ VPXOR v1, v7, v7; \
+ VPSHUFD $-79, v6, v6; \
+ VPSHUFD $-79, v7, v7; \
+ VPADDQ v6, v4, v4; \
+ VPADDQ v7, v5, v5; \
+ VPXOR v4, v2, v2; \
+ VPXOR v5, v3, v3; \
+ VPSHUFB c40, v2, v2; \
+ VPSHUFB c40, v3, v3; \
+ VPADDQ m2, v0, v0; \
+ VPADDQ v2, v0, v0; \
+ VPADDQ m3, v1, v1; \
+ VPADDQ v3, v1, v1; \
+ VPXOR v0, v6, v6; \
+ VPXOR v1, v7, v7; \
+ VPSHUFB c48, v6, v6; \
+ VPSHUFB c48, v7, v7; \
+ VPADDQ v6, v4, v4; \
+ VPADDQ v7, v5, v5; \
+ VPXOR v4, v2, v2; \
+ VPXOR v5, v3, v3; \
+ VPADDQ v2, v2, t0; \
+ VPSRLQ $63, v2, v2; \
+ VPXOR t0, v2, v2; \
+ VPADDQ v3, v3, t0; \
+ VPSRLQ $63, v3, v3; \
+ VPXOR t0, v3, v3
+
+// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7)
+// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0
+#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \
+ VMOVQ_SI_X12(i0*8); \
+ VMOVQ_SI_X13(i2*8); \
+ VMOVQ_SI_X14(i4*8); \
+ VMOVQ_SI_X15(i6*8); \
+ VPINSRQ_1_SI_X12(i1*8); \
+ VPINSRQ_1_SI_X13(i3*8); \
+ VPINSRQ_1_SI_X14(i5*8); \
+ VPINSRQ_1_SI_X15(i7*8)
+
+// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7)
+#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \
+ VMOVQ_SI_X12_0; \
+ VMOVQ_SI_X13(4*8); \
+ VMOVQ_SI_X14(1*8); \
+ VMOVQ_SI_X15(5*8); \
+ VPINSRQ_1_SI_X12(2*8); \
+ VPINSRQ_1_SI_X13(6*8); \
+ VPINSRQ_1_SI_X14(3*8); \
+ VPINSRQ_1_SI_X15(7*8)
+
+// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3)
+#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \
+ VPSHUFD $0x4E, 0*8(SI), X12; \
+ VMOVQ_SI_X13(11*8); \
+ VMOVQ_SI_X14(12*8); \
+ VMOVQ_SI_X15(7*8); \
+ VPINSRQ_1_SI_X13(5*8); \
+ VPINSRQ_1_SI_X14(2*8); \
+ VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13)
+#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \
+ VMOVDQU 11*8(SI), X12; \
+ VMOVQ_SI_X13(5*8); \
+ VMOVQ_SI_X14(8*8); \
+ VMOVQ_SI_X15(2*8); \
+ VPINSRQ_1_SI_X13(15*8); \
+ VPINSRQ_1_SI_X14_0; \
+ VPINSRQ_1_SI_X15(13*8)
+
+// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8)
+#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \
+ VMOVQ_SI_X12(2*8); \
+ VMOVQ_SI_X13(4*8); \
+ VMOVQ_SI_X14(6*8); \
+ VMOVQ_SI_X15_0; \
+ VPINSRQ_1_SI_X12(5*8); \
+ VPINSRQ_1_SI_X13(15*8); \
+ VPINSRQ_1_SI_X14(10*8); \
+ VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15)
+#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \
+ VMOVQ_SI_X12(9*8); \
+ VMOVQ_SI_X13(2*8); \
+ VMOVQ_SI_X14_0; \
+ VMOVQ_SI_X15(4*8); \
+ VPINSRQ_1_SI_X12(5*8); \
+ VPINSRQ_1_SI_X13(10*8); \
+ VPINSRQ_1_SI_X14(7*8); \
+ VPINSRQ_1_SI_X15(15*8)
+
+// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3)
+#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \
+ VMOVQ_SI_X12(2*8); \
+ VMOVQ_SI_X13_0; \
+ VMOVQ_SI_X14(12*8); \
+ VMOVQ_SI_X15(11*8); \
+ VPINSRQ_1_SI_X12(6*8); \
+ VPINSRQ_1_SI_X13(8*8); \
+ VPINSRQ_1_SI_X14(10*8); \
+ VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11)
+#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \
+ MOVQ 0*8(SI), X12; \
+ VPSHUFD $0x4E, 8*8(SI), X13; \
+ MOVQ 7*8(SI), X14; \
+ MOVQ 2*8(SI), X15; \
+ VPINSRQ_1_SI_X12(6*8); \
+ VPINSRQ_1_SI_X14(3*8); \
+ VPINSRQ_1_SI_X15(11*8)
+
+// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8)
+#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \
+ MOVQ 6*8(SI), X12; \
+ MOVQ 11*8(SI), X13; \
+ MOVQ 15*8(SI), X14; \
+ MOVQ 3*8(SI), X15; \
+ VPINSRQ_1_SI_X12(14*8); \
+ VPINSRQ_1_SI_X13_0; \
+ VPINSRQ_1_SI_X14(9*8); \
+ VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10)
+#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \
+ MOVQ 5*8(SI), X12; \
+ MOVQ 8*8(SI), X13; \
+ MOVQ 0*8(SI), X14; \
+ MOVQ 6*8(SI), X15; \
+ VPINSRQ_1_SI_X12(15*8); \
+ VPINSRQ_1_SI_X13(2*8); \
+ VPINSRQ_1_SI_X14(4*8); \
+ VPINSRQ_1_SI_X15(10*8)
+
+// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5)
+#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \
+ VMOVDQU 12*8(SI), X12; \
+ MOVQ 1*8(SI), X13; \
+ MOVQ 2*8(SI), X14; \
+ VPINSRQ_1_SI_X13(10*8); \
+ VPINSRQ_1_SI_X14(7*8); \
+ VMOVDQU 4*8(SI), X15
+
+// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0)
+#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \
+ MOVQ 15*8(SI), X12; \
+ MOVQ 3*8(SI), X13; \
+ MOVQ 11*8(SI), X14; \
+ MOVQ 12*8(SI), X15; \
+ VPINSRQ_1_SI_X12(9*8); \
+ VPINSRQ_1_SI_X13(13*8); \
+ VPINSRQ_1_SI_X14(14*8); \
+ VPINSRQ_1_SI_X15_0
+
+// func fAVX(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+TEXT ·fAVX(SB), 4, $24-48 // frame size = 8 + 16 byte alignment
+ MOVQ h+0(FP), AX
+ MOVQ m+8(FP), SI
+ MOVQ c0+16(FP), R8
+ MOVQ c1+24(FP), R9
+ MOVQ flag+32(FP), CX
+ MOVQ rounds+40(FP), BX
+
+ MOVQ SP, BP
+ MOVQ SP, R10
+ ADDQ $15, R10
+ ANDQ $~15, R10
+ MOVQ R10, SP
+
+ VMOVDQU ·AVX_c40<>(SB), X0
+ VMOVDQU ·AVX_c48<>(SB), X1
+ VMOVDQA X0, X8
+ VMOVDQA X1, X9
+
+ VMOVDQU ·AVX_iv3<>(SB), X0
+ VMOVDQA X0, 0(SP)
+ XORQ CX, 0(SP) // 0(SP) = ·AVX_iv3 ^ (CX || 0)
+
+ VMOVDQU 0(AX), X10
+ VMOVDQU 16(AX), X11
+ VMOVDQU 32(AX), X2
+ VMOVDQU 48(AX), X3
+
+ VMOVQ_R8_X15
+ VPINSRQ_1_R9_X15
+
+ VMOVDQA X10, X0
+ VMOVDQA X11, X1
+ VMOVDQU ·AVX_iv0<>(SB), X4
+ VMOVDQU ·AVX_iv1<>(SB), X5
+ VMOVDQU ·AVX_iv2<>(SB), X6
+
+ VPXOR X15, X6, X6
+ VMOVDQA 0(SP), X7
+
+loop:
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX_0_2_4_6_1_3_5_7()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_1_0_11_5_12_2_7_3()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX_11_12_5_15_8_0_2_13()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_2_5_4_15_6_10_0_8()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX_9_5_2_10_0_7_4_15()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX_2_6_0_8_12_10_11_3()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_0_6_9_8_7_3_2_11()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_5_15_8_2_0_4_6_10()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX_6_14_11_0_15_9_3_8()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_12_13_1_10_2_7_4_5()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5)
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX()
+ LOAD_MSG_AVX_15_9_3_13_11_14_12_0()
+ HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+ SHUFFLE_AVX_INV()
+
+ JMP loop
+
+done:
+ VMOVDQU 32(AX), X14
+ VMOVDQU 48(AX), X15
+ VPXOR X0, X10, X10
+ VPXOR X1, X11, X11
+ VPXOR X2, X14, X14
+ VPXOR X3, X15, X15
+ VPXOR X4, X10, X10
+ VPXOR X5, X11, X11
+ VPXOR X6, X14, X2
+ VPXOR X7, X15, X3
+ VMOVDQU X2, 32(AX)
+ VMOVDQU X3, 48(AX)
+
+ VMOVDQU X10, 0(AX)
+ VMOVDQU X11, 16(AX)
+ VZEROUPPER
+
+ MOVQ BP, SP
+ RET
diff --git a/crypto/blake2b/blake2b_amd64.go b/crypto/blake2b/blake2b_amd64.go
new file mode 100644
index 0000000000..4dbe90da8f
--- /dev/null
+++ b/crypto/blake2b/blake2b_amd64.go
@@ -0,0 +1,24 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.7,amd64,!gccgo,!appengine
+
+package blake2b
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+ useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func fSSE4(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+
+func f(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
+ if useSSE4 {
+ fSSE4(h, m, c0, c1, flag, rounds)
+ } else {
+ fGeneric(h, m, c0, c1, flag, rounds)
+ }
+}
diff --git a/crypto/blake2b/blake2b_amd64.s b/crypto/blake2b/blake2b_amd64.s
new file mode 100644
index 0000000000..ce4b56d105
--- /dev/null
+++ b/crypto/blake2b/blake2b_amd64.s
@@ -0,0 +1,253 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64,!gccgo,!appengine
+
+#include "textflag.h"
+
+DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
+
+#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
+ MOVO v4, t1; \
+ MOVO v5, v4; \
+ MOVO t1, v5; \
+ MOVO v6, t1; \
+ PUNPCKLQDQ v6, t2; \
+ PUNPCKHQDQ v7, v6; \
+ PUNPCKHQDQ t2, v6; \
+ PUNPCKLQDQ v7, t2; \
+ MOVO t1, v7; \
+ MOVO v2, t1; \
+ PUNPCKHQDQ t2, v7; \
+ PUNPCKLQDQ v3, t2; \
+ PUNPCKHQDQ t2, v2; \
+ PUNPCKLQDQ t1, t2; \
+ PUNPCKHQDQ t2, v3
+
+#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
+ MOVO v4, t1; \
+ MOVO v5, v4; \
+ MOVO t1, v5; \
+ MOVO v2, t1; \
+ PUNPCKLQDQ v2, t2; \
+ PUNPCKHQDQ v3, v2; \
+ PUNPCKHQDQ t2, v2; \
+ PUNPCKLQDQ v3, t2; \
+ MOVO t1, v3; \
+ MOVO v6, t1; \
+ PUNPCKHQDQ t2, v3; \
+ PUNPCKLQDQ v7, t2; \
+ PUNPCKHQDQ t2, v6; \
+ PUNPCKLQDQ t1, t2; \
+ PUNPCKHQDQ t2, v7
+
+#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+ PADDQ m0, v0; \
+ PADDQ m1, v1; \
+ PADDQ v2, v0; \
+ PADDQ v3, v1; \
+ PXOR v0, v6; \
+ PXOR v1, v7; \
+ PSHUFD $0xB1, v6, v6; \
+ PSHUFD $0xB1, v7, v7; \
+ PADDQ v6, v4; \
+ PADDQ v7, v5; \
+ PXOR v4, v2; \
+ PXOR v5, v3; \
+ PSHUFB c40, v2; \
+ PSHUFB c40, v3; \
+ PADDQ m2, v0; \
+ PADDQ m3, v1; \
+ PADDQ v2, v0; \
+ PADDQ v3, v1; \
+ PXOR v0, v6; \
+ PXOR v1, v7; \
+ PSHUFB c48, v6; \
+ PSHUFB c48, v7; \
+ PADDQ v6, v4; \
+ PADDQ v7, v5; \
+ PXOR v4, v2; \
+ PXOR v5, v3; \
+ MOVOU v2, t0; \
+ PADDQ v2, t0; \
+ PSRLQ $63, v2; \
+ PXOR t0, v2; \
+ MOVOU v3, t0; \
+ PADDQ v3, t0; \
+ PSRLQ $63, v3; \
+ PXOR t0, v3
+
+#define LOAD_MSG(m0, m1, m2, m3, i0, i1, i2, i3, i4, i5, i6, i7) \
+ MOVQ i0*8(SI), m0; \
+ PINSRQ $1, i1*8(SI), m0; \
+ MOVQ i2*8(SI), m1; \
+ PINSRQ $1, i3*8(SI), m1; \
+ MOVQ i4*8(SI), m2; \
+ PINSRQ $1, i5*8(SI), m2; \
+ MOVQ i6*8(SI), m3; \
+ PINSRQ $1, i7*8(SI), m3
+
+// func fSSE4(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64)
+TEXT ·fSSE4(SB), 4, $24-48 // frame size = 8 + 16 byte alignment
+ MOVQ h+0(FP), AX
+ MOVQ m+8(FP), SI
+ MOVQ c0+16(FP), R8
+ MOVQ c1+24(FP), R9
+ MOVQ flag+32(FP), CX
+ MOVQ rounds+40(FP), BX
+
+ MOVQ SP, BP
+ MOVQ SP, R10
+ ADDQ $15, R10
+ ANDQ $~15, R10
+ MOVQ R10, SP
+
+ MOVOU ·iv3<>(SB), X0
+ MOVO X0, 0(SP)
+ XORQ CX, 0(SP) // 0(SP) = ·iv3 ^ (CX || 0)
+
+ MOVOU ·c40<>(SB), X13
+ MOVOU ·c48<>(SB), X14
+
+ MOVOU 0(AX), X12
+ MOVOU 16(AX), X15
+
+ MOVQ R8, X8
+ PINSRQ $1, R9, X8
+
+ MOVO X12, X0
+ MOVO X15, X1
+ MOVOU 32(AX), X2
+ MOVOU 48(AX), X3
+ MOVOU ·iv0<>(SB), X4
+ MOVOU ·iv1<>(SB), X5
+ MOVOU ·iv2<>(SB), X6
+
+ PXOR X8, X6
+ MOVO 0(SP), X7
+
+loop:
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 0, 2, 4, 6, 1, 3, 5, 7)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 8, 10, 12, 14, 9, 11, 13, 15)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 14, 4, 9, 13, 10, 8, 15, 6)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 1, 0, 11, 5, 12, 2, 7, 3)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 11, 12, 5, 15, 8, 0, 2, 13)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 10, 3, 7, 9, 14, 6, 1, 4)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 7, 3, 13, 11, 9, 1, 12, 14)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 2, 5, 4, 15, 6, 10, 0, 8)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 9, 5, 2, 10, 0, 7, 4, 15)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 14, 11, 6, 3, 1, 12, 8, 13)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 2, 6, 0, 8, 12, 10, 11, 3)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 4, 7, 15, 1, 13, 5, 14, 9)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 12, 1, 14, 4, 5, 15, 13, 10)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 0, 6, 9, 8, 7, 3, 2, 11)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 13, 7, 12, 3, 11, 14, 1, 9)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 5, 15, 8, 2, 0, 4, 6, 10)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 6, 14, 11, 0, 15, 9, 3, 8)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 12, 13, 1, 10, 2, 7, 4, 5)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ SUBQ $1, BX; JCS done
+ LOAD_MSG(X8, X9, X10, X11, 10, 8, 7, 1, 2, 4, 6, 5)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+ LOAD_MSG(X8, X9, X10, X11, 15, 9, 3, 13, 11, 14, 12, 0)
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+ JMP loop
+
+done:
+ MOVOU 32(AX), X10
+ MOVOU 48(AX), X11
+ PXOR X0, X12
+ PXOR X1, X15
+ PXOR X2, X10
+ PXOR X3, X11
+ PXOR X4, X12
+ PXOR X5, X15
+ PXOR X6, X10
+ PXOR X7, X11
+ MOVOU X10, 32(AX)
+ MOVOU X11, 48(AX)
+
+ MOVOU X12, 0(AX)
+ MOVOU X15, 16(AX)
+
+ MOVQ BP, SP
+ RET
diff --git a/crypto/blake2b/blake2b_f_fuzz.go b/crypto/blake2b/blake2b_f_fuzz.go
new file mode 100644
index 0000000000..ab73342803
--- /dev/null
+++ b/crypto/blake2b/blake2b_f_fuzz.go
@@ -0,0 +1,57 @@
+// +build gofuzz
+
+package blake2b
+
+import (
+ "encoding/binary"
+)
+
+func Fuzz(data []byte) int {
+ // Make sure the data confirms to the input model
+ if len(data) != 211 {
+ return 0
+ }
+ // Parse everything and call all the implementations
+ var (
+ rounds = binary.BigEndian.Uint16(data[0:2])
+
+ h [8]uint64
+ m [16]uint64
+ t [2]uint64
+ f uint64
+ )
+ for i := 0; i < 8; i++ {
+ offset := 2 + i*8
+ h[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
+ }
+ for i := 0; i < 16; i++ {
+ offset := 66 + i*8
+ m[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
+ }
+ t[0] = binary.LittleEndian.Uint64(data[194:202])
+ t[1] = binary.LittleEndian.Uint64(data[202:210])
+
+ if data[210]%2 == 1 { // Avoid spinning the fuzzer to hit 0/1
+ f = 0xFFFFFFFFFFFFFFFF
+ }
+ // Run the blake2b compression on all instruction sets and cross reference
+ want := h
+ fGeneric(&want, &m, t[0], t[1], f, uint64(rounds))
+
+ have := h
+ fSSE4(&have, &m, t[0], t[1], f, uint64(rounds))
+ if have != want {
+ panic("SSE4 mismatches generic algo")
+ }
+ have = h
+ fAVX(&have, &m, t[0], t[1], f, uint64(rounds))
+ if have != want {
+ panic("AVX mismatches generic algo")
+ }
+ have = h
+ fAVX2(&have, &m, t[0], t[1], f, uint64(rounds))
+ if have != want {
+ panic("AVX2 mismatches generic algo")
+ }
+ return 1
+}
diff --git a/crypto/blake2b/blake2b_f_test.go b/crypto/blake2b/blake2b_f_test.go
new file mode 100644
index 0000000000..4e07d131cd
--- /dev/null
+++ b/crypto/blake2b/blake2b_f_test.go
@@ -0,0 +1,59 @@
+package blake2b
+
+import (
+ "fmt"
+ "reflect"
+ "testing"
+)
+
+func TestF(t *testing.T) {
+ for i, test := range testVectorsF {
+ t.Run(fmt.Sprintf("test vector %v", i), func(t *testing.T) {
+ //toEthereumTestCase(test)
+
+ h := test.hIn
+ F(&h, test.m, test.c, test.f, test.rounds)
+
+ if !reflect.DeepEqual(test.hOut, h) {
+ t.Errorf("Unexpected result\nExpected: [%#x]\nActual: [%#x]\n", test.hOut, h)
+ }
+ })
+ }
+}
+
+type testVector struct {
+ hIn [8]uint64
+ m [16]uint64
+ c [2]uint64
+ f bool
+ rounds uint32
+ hOut [8]uint64
+}
+
+// https://tools.ietf.org/html/rfc7693#appendix-A
+var testVectorsF = []testVector{
+ {
+ hIn: [8]uint64{
+ 0x6a09e667f2bdc948, 0xbb67ae8584caa73b,
+ 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+ 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
+ 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
+ },
+ m: [16]uint64{
+ 0x0000000000636261, 0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000,
+ },
+ c: [2]uint64{3, 0},
+ f: true,
+ rounds: 12,
+ hOut: [8]uint64{
+ 0x0D4D1C983FA580BA, 0xE9F6129FB697276A, 0xB7C45A68142F214C,
+ 0xD1A2FFDB6FBB124B, 0x2D79AB2A39C5877D, 0x95CC3345DED552C2,
+ 0x5A92F1DBA88AD318, 0x239900D4ED8623B9,
+ },
+ },
+}
diff --git a/crypto/blake2b/blake2b_generic.go b/crypto/blake2b/blake2b_generic.go
new file mode 100644
index 0000000000..35c40cc924
--- /dev/null
+++ b/crypto/blake2b/blake2b_generic.go
@@ -0,0 +1,180 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+// the precomputed values for BLAKE2b
+// there are 10 16-byte arrays - one for each round
+// the entries are calculated from the sigma constants.
+var precomputed = [10][16]byte{
+ {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
+ {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
+ {11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
+ {7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
+ {9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
+ {2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
+ {12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
+ {13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
+ {6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
+ {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
+}
+
+func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+ var m [16]uint64
+ c0, c1 := c[0], c[1]
+
+ for i := 0; i < len(blocks); {
+ c0 += BlockSize
+ if c0 < BlockSize {
+ c1++
+ }
+ for j := range m {
+ m[j] = binary.LittleEndian.Uint64(blocks[i:])
+ i += 8
+ }
+ fGeneric(h, &m, c0, c1, flag, 12)
+ }
+ c[0], c[1] = c0, c1
+}
+
+func fGeneric(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
+ v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
+ v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
+ v12 ^= c0
+ v13 ^= c1
+ v14 ^= flag
+
+ for i := 0; i < int(rounds); i++ {
+ s := &(precomputed[i%10])
+
+ v0 += m[s[0]]
+ v0 += v4
+ v12 ^= v0
+ v12 = bits.RotateLeft64(v12, -32)
+ v8 += v12
+ v4 ^= v8
+ v4 = bits.RotateLeft64(v4, -24)
+ v1 += m[s[1]]
+ v1 += v5
+ v13 ^= v1
+ v13 = bits.RotateLeft64(v13, -32)
+ v9 += v13
+ v5 ^= v9
+ v5 = bits.RotateLeft64(v5, -24)
+ v2 += m[s[2]]
+ v2 += v6
+ v14 ^= v2
+ v14 = bits.RotateLeft64(v14, -32)
+ v10 += v14
+ v6 ^= v10
+ v6 = bits.RotateLeft64(v6, -24)
+ v3 += m[s[3]]
+ v3 += v7
+ v15 ^= v3
+ v15 = bits.RotateLeft64(v15, -32)
+ v11 += v15
+ v7 ^= v11
+ v7 = bits.RotateLeft64(v7, -24)
+
+ v0 += m[s[4]]
+ v0 += v4
+ v12 ^= v0
+ v12 = bits.RotateLeft64(v12, -16)
+ v8 += v12
+ v4 ^= v8
+ v4 = bits.RotateLeft64(v4, -63)
+ v1 += m[s[5]]
+ v1 += v5
+ v13 ^= v1
+ v13 = bits.RotateLeft64(v13, -16)
+ v9 += v13
+ v5 ^= v9
+ v5 = bits.RotateLeft64(v5, -63)
+ v2 += m[s[6]]
+ v2 += v6
+ v14 ^= v2
+ v14 = bits.RotateLeft64(v14, -16)
+ v10 += v14
+ v6 ^= v10
+ v6 = bits.RotateLeft64(v6, -63)
+ v3 += m[s[7]]
+ v3 += v7
+ v15 ^= v3
+ v15 = bits.RotateLeft64(v15, -16)
+ v11 += v15
+ v7 ^= v11
+ v7 = bits.RotateLeft64(v7, -63)
+
+ v0 += m[s[8]]
+ v0 += v5
+ v15 ^= v0
+ v15 = bits.RotateLeft64(v15, -32)
+ v10 += v15
+ v5 ^= v10
+ v5 = bits.RotateLeft64(v5, -24)
+ v1 += m[s[9]]
+ v1 += v6
+ v12 ^= v1
+ v12 = bits.RotateLeft64(v12, -32)
+ v11 += v12
+ v6 ^= v11
+ v6 = bits.RotateLeft64(v6, -24)
+ v2 += m[s[10]]
+ v2 += v7
+ v13 ^= v2
+ v13 = bits.RotateLeft64(v13, -32)
+ v8 += v13
+ v7 ^= v8
+ v7 = bits.RotateLeft64(v7, -24)
+ v3 += m[s[11]]
+ v3 += v4
+ v14 ^= v3
+ v14 = bits.RotateLeft64(v14, -32)
+ v9 += v14
+ v4 ^= v9
+ v4 = bits.RotateLeft64(v4, -24)
+
+ v0 += m[s[12]]
+ v0 += v5
+ v15 ^= v0
+ v15 = bits.RotateLeft64(v15, -16)
+ v10 += v15
+ v5 ^= v10
+ v5 = bits.RotateLeft64(v5, -63)
+ v1 += m[s[13]]
+ v1 += v6
+ v12 ^= v1
+ v12 = bits.RotateLeft64(v12, -16)
+ v11 += v12
+ v6 ^= v11
+ v6 = bits.RotateLeft64(v6, -63)
+ v2 += m[s[14]]
+ v2 += v7
+ v13 ^= v2
+ v13 = bits.RotateLeft64(v13, -16)
+ v8 += v13
+ v7 ^= v8
+ v7 = bits.RotateLeft64(v7, -63)
+ v3 += m[s[15]]
+ v3 += v4
+ v14 ^= v3
+ v14 = bits.RotateLeft64(v14, -16)
+ v9 += v14
+ v4 ^= v9
+ v4 = bits.RotateLeft64(v4, -63)
+ }
+ h[0] ^= v0 ^ v8
+ h[1] ^= v1 ^ v9
+ h[2] ^= v2 ^ v10
+ h[3] ^= v3 ^ v11
+ h[4] ^= v4 ^ v12
+ h[5] ^= v5 ^ v13
+ h[6] ^= v6 ^ v14
+ h[7] ^= v7 ^ v15
+}
diff --git a/crypto/blake2b/blake2b_ref.go b/crypto/blake2b/blake2b_ref.go
new file mode 100644
index 0000000000..9d0ade473a
--- /dev/null
+++ b/crypto/blake2b/blake2b_ref.go
@@ -0,0 +1,11 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64 appengine gccgo
+
+package blake2b
+
+func f(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
+ fGeneric(h, m, c0, c1, flag, rounds)
+}
diff --git a/crypto/blake2b/blake2b_test.go b/crypto/blake2b/blake2b_test.go
new file mode 100644
index 0000000000..9e7297da16
--- /dev/null
+++ b/crypto/blake2b/blake2b_test.go
@@ -0,0 +1,871 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/hex"
+ "fmt"
+ "hash"
+ "io"
+ "testing"
+)
+
+func fromHex(s string) []byte {
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func TestHashes(t *testing.T) {
+ defer func(sse4, avx, avx2 bool) {
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+ }(useSSE4, useAVX, useAVX2)
+
+ if useAVX2 {
+ t.Log("AVX2 version")
+ testHashes(t)
+ useAVX2 = false
+ }
+ if useAVX {
+ t.Log("AVX version")
+ testHashes(t)
+ useAVX = false
+ }
+ if useSSE4 {
+ t.Log("SSE4 version")
+ testHashes(t)
+ useSSE4 = false
+ }
+ t.Log("generic version")
+ testHashes(t)
+}
+
+func TestHashes2X(t *testing.T) {
+ defer func(sse4, avx, avx2 bool) {
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+ }(useSSE4, useAVX, useAVX2)
+
+ if useAVX2 {
+ t.Log("AVX2 version")
+ testHashes2X(t)
+ useAVX2 = false
+ }
+ if useAVX {
+ t.Log("AVX version")
+ testHashes2X(t)
+ useAVX = false
+ }
+ if useSSE4 {
+ t.Log("SSE4 version")
+ testHashes2X(t)
+ useSSE4 = false
+ }
+ t.Log("generic version")
+ testHashes2X(t)
+}
+
+func TestMarshal(t *testing.T) {
+ input := make([]byte, 255)
+ for i := range input {
+ input[i] = byte(i)
+ }
+ for _, size := range []int{Size, Size256, Size384, 12, 25, 63} {
+ for i := 0; i < 256; i++ {
+ h, err := New(size, nil)
+ if err != nil {
+ t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
+ }
+ h2, err := New(size, nil)
+ if err != nil {
+ t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
+ }
+
+ h.Write(input[:i/2])
+ halfstate, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+ if err != nil {
+ t.Fatalf("size=%d, len(input)=%d: could not marshal: %v", size, i, err)
+ }
+ err = h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(halfstate)
+ if err != nil {
+ t.Fatalf("size=%d, len(input)=%d: could not unmarshal: %v", size, i, err)
+ }
+
+ h.Write(input[i/2 : i])
+ sum := h.Sum(nil)
+ h2.Write(input[i/2 : i])
+ sum2 := h2.Sum(nil)
+
+ if !bytes.Equal(sum, sum2) {
+ t.Fatalf("size=%d, len(input)=%d: results do not match; sum = %v, sum2 = %v", size, i, sum, sum2)
+ }
+
+ h3, err := New(size, nil)
+ if err != nil {
+ t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
+ }
+ h3.Write(input[:i])
+ sum3 := h3.Sum(nil)
+ if !bytes.Equal(sum, sum3) {
+ t.Fatalf("size=%d, len(input)=%d: sum = %v, want %v", size, i, sum, sum3)
+ }
+ }
+ }
+}
+
+func testHashes(t *testing.T) {
+ key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")
+
+ input := make([]byte, 255)
+ for i := range input {
+ input[i] = byte(i)
+ }
+
+ for i, expectedHex := range hashes {
+ h, err := New512(key)
+ if err != nil {
+ t.Fatalf("#%d: error from New512: %v", i, err)
+ }
+
+ h.Write(input[:i])
+ sum := h.Sum(nil)
+
+ if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
+ t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
+ }
+
+ h.Reset()
+ for j := 0; j < i; j++ {
+ h.Write(input[j : j+1])
+ }
+
+ sum = h.Sum(sum[:0])
+ if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
+ t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
+ }
+ }
+}
+
+func testHashes2X(t *testing.T) {
+ key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")
+
+ input := make([]byte, 256)
+ for i := range input {
+ input[i] = byte(i)
+ }
+
+ for i, expectedHex := range hashes2X {
+ length := uint32(len(expectedHex) / 2)
+ sum := make([]byte, int(length))
+
+ h, err := NewXOF(length, key)
+ if err != nil {
+ t.Fatalf("#%d: error from NewXOF: %v", i, err)
+ }
+
+ if _, err := h.Write(input); err != nil {
+ t.Fatalf("#%d (single write): error from Write: %v", i, err)
+ }
+ if _, err := h.Read(sum); err != nil {
+ t.Fatalf("#%d (single write): error from Read: %v", i, err)
+ }
+ if n, err := h.Read(sum); n != 0 || err != io.EOF {
+ t.Fatalf("#%d (single write): Read did not return (0, io.EOF) after exhaustion, got (%v, %v)", i, n, err)
+ }
+ if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
+ t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
+ }
+
+ h.Reset()
+ for j := 0; j < len(input); j++ {
+ h.Write(input[j : j+1])
+ }
+ for j := 0; j < len(sum); j++ {
+ h = h.Clone()
+ if _, err := h.Read(sum[j : j+1]); err != nil {
+ t.Fatalf("#%d (byte-by-byte) - Read %d: error from Read: %v", i, j, err)
+ }
+ }
+ if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
+ t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
+ }
+ }
+
+ h, err := NewXOF(OutputLengthUnknown, key)
+ if err != nil {
+ t.Fatalf("#unknown length: error from NewXOF: %v", err)
+ }
+ if _, err := h.Write(input); err != nil {
+ t.Fatalf("#unknown length: error from Write: %v", err)
+ }
+
+ var result [64]byte
+ if n, err := h.Read(result[:]); err != nil {
+ t.Fatalf("#unknown length: error from Read: %v", err)
+ } else if n != len(result) {
+ t.Fatalf("#unknown length: Read returned %d bytes, want %d", n, len(result))
+ }
+
+ const expected = "3dbba8516da76bf7330055c66ea36cf1005e92714262b24d9710f51d9e126406e1bcd6497059f9331f1091c3634b695428d475ed432f987040575520a1c29f5e"
+ if fmt.Sprintf("%x", result) != expected {
+ t.Fatalf("#unknown length: bad result %x, wanted %s", result, expected)
+ }
+}
+
+func generateSequence(out []byte, seed uint32) {
+ a := 0xDEAD4BAD * seed // prime
+ b := uint32(1)
+
+ for i := range out { // fill the buf
+ a, b = b, a+b
+ out[i] = byte(b >> 24)
+ }
+}
+
+func computeMAC(msg []byte, hashSize int, key []byte) (sum []byte) {
+ var h hash.Hash
+ switch hashSize {
+ case Size:
+ h, _ = New512(key)
+ case Size384:
+ h, _ = New384(key)
+ case Size256:
+ h, _ = New256(key)
+ case 20:
+ h, _ = newDigest(20, key)
+ default:
+ panic("unexpected hashSize")
+ }
+
+ h.Write(msg)
+ return h.Sum(sum)
+}
+
+func computeHash(msg []byte, hashSize int) (sum []byte) {
+ switch hashSize {
+ case Size:
+ hash := Sum512(msg)
+ return hash[:]
+ case Size384:
+ hash := Sum384(msg)
+ return hash[:]
+ case Size256:
+ hash := Sum256(msg)
+ return hash[:]
+ case 20:
+ var hash [64]byte
+ checkSum(&hash, 20, msg)
+ return hash[:20]
+ default:
+ panic("unexpected hashSize")
+ }
+}
+
+// Test function from RFC 7693.
+func TestSelfTest(t *testing.T) {
+ hashLens := [4]int{20, 32, 48, 64}
+ msgLens := [6]int{0, 3, 128, 129, 255, 1024}
+
+ msg := make([]byte, 1024)
+ key := make([]byte, 64)
+
+ h, _ := New256(nil)
+ for _, hashSize := range hashLens {
+ for _, msgLength := range msgLens {
+ generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash
+
+ md := computeHash(msg[:msgLength], hashSize)
+ h.Write(md)
+
+ generateSequence(key[:], uint32(hashSize)) // keyed hash
+ md = computeMAC(msg[:msgLength], hashSize, key[:hashSize])
+ h.Write(md)
+ }
+ }
+
+ sum := h.Sum(nil)
+ expected := [32]byte{
+ 0xc2, 0x3a, 0x78, 0x00, 0xd9, 0x81, 0x23, 0xbd,
+ 0x10, 0xf5, 0x06, 0xc6, 0x1e, 0x29, 0xda, 0x56,
+ 0x03, 0xd7, 0x63, 0xb8, 0xbb, 0xad, 0x2e, 0x73,
+ 0x7f, 0x5e, 0x76, 0x5a, 0x7b, 0xcc, 0xd4, 0x75,
+ }
+ if !bytes.Equal(sum, expected[:]) {
+ t.Fatalf("got %x, wanted %x", sum, expected)
+ }
+}
+
+// Benchmarks
+
+func benchmarkSum(b *testing.B, size int, sse4, avx, avx2 bool) {
+ // Enable the correct set of instructions
+ defer func(sse4, avx, avx2 bool) {
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+ }(useSSE4, useAVX, useAVX2)
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+
+ data := make([]byte, size)
+ b.SetBytes(int64(size))
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ Sum512(data)
+ }
+}
+
+func benchmarkWrite(b *testing.B, size int, sse4, avx, avx2 bool) {
+ // Enable the correct set of instructions
+ defer func(sse4, avx, avx2 bool) {
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+ }(useSSE4, useAVX, useAVX2)
+ useSSE4, useAVX, useAVX2 = sse4, avx, avx2
+
+ data := make([]byte, size)
+ h, _ := New512(nil)
+ b.SetBytes(int64(size))
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ h.Write(data)
+ }
+}
+
+func BenchmarkWrite128Generic(b *testing.B) { benchmarkWrite(b, 128, false, false, false) }
+func BenchmarkWrite1KGeneric(b *testing.B) { benchmarkWrite(b, 1024, false, false, false) }
+func BenchmarkWrite128SSE4(b *testing.B) { benchmarkWrite(b, 128, true, false, false) }
+func BenchmarkWrite1KSSE4(b *testing.B) { benchmarkWrite(b, 1024, true, false, false) }
+func BenchmarkWrite128AVX(b *testing.B) { benchmarkWrite(b, 128, false, true, false) }
+func BenchmarkWrite1KAVX(b *testing.B) { benchmarkWrite(b, 1024, false, true, false) }
+func BenchmarkWrite128AVX2(b *testing.B) { benchmarkWrite(b, 128, false, false, true) }
+func BenchmarkWrite1KAVX2(b *testing.B) { benchmarkWrite(b, 1024, false, false, true) }
+
+func BenchmarkSum128Generic(b *testing.B) { benchmarkSum(b, 128, false, false, false) }
+func BenchmarkSum1KGeneric(b *testing.B) { benchmarkSum(b, 1024, false, false, false) }
+func BenchmarkSum128SSE4(b *testing.B) { benchmarkSum(b, 128, true, false, false) }
+func BenchmarkSum1KSSE4(b *testing.B) { benchmarkSum(b, 1024, true, false, false) }
+func BenchmarkSum128AVX(b *testing.B) { benchmarkSum(b, 128, false, true, false) }
+func BenchmarkSum1KAVX(b *testing.B) { benchmarkSum(b, 1024, false, true, false) }
+func BenchmarkSum128AVX2(b *testing.B) { benchmarkSum(b, 128, false, false, true) }
+func BenchmarkSum1KAVX2(b *testing.B) { benchmarkSum(b, 1024, false, false, true) }
+
+// These values were taken from https://blake2.net/blake2b-test.txt.
+var hashes = []string{
+ "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568",
+ "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd",
+ "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965",
+ "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1",
+ "beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac",
+ "098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb",
+ "6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f",
+ "7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52",
+ "380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9",
+ "60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637",
+ "4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd",
+ "f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b",
+ "962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563",
+ "43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355",
+ "dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6",
+ "6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e",
+ "a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93",
+ "f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1",
+ "95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670",
+ "04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9",
+ "ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c",
+ "9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd",
+ "4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152",
+ "64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9",
+ "5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f",
+ "7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b",
+ "f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764",
+ "86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d",
+ "10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55",
+ "b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b",
+ "c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e",
+ "eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7",
+ "86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991",
+ "5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347",
+ "ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82",
+ "7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42",
+ "940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327",
+ "2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760",
+ "d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252",
+ "b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55",
+ "4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1",
+ "258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee",
+ "79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa",
+ "8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7",
+ "c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071",
+ "b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4",
+ "7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf",
+ "a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d",
+ "41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8",
+ "14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487",
+ "d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c",
+ "e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2",
+ "feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa",
+ "462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33",
+ "d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d",
+ "e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e",
+ "f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2",
+ "30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4",
+ "f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2",
+ "0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a",
+ "08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564",
+ "d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f",
+ "dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9",
+ "bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa",
+ "65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022",
+ "939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c",
+ "c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc",
+ "987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f",
+ "ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b",
+ "49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866",
+ "da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d",
+ "d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8",
+ "2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4",
+ "e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3",
+ "dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e",
+ "d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745",
+ "b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545",
+ "6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063",
+ "f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd",
+ "cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a",
+ "fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed",
+ "5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd",
+ "9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275",
+ "af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897",
+ "48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430",
+ "0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab",
+ "06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f",
+ "1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46",
+ "3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29",
+ "04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab",
+ "9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8",
+ "ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a",
+ "8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec",
+ "fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79",
+ "28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24",
+ "ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b",
+ "b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5",
+ "31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463",
+ "bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4",
+ "f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3",
+ "8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9",
+ "c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d",
+ "4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4",
+ "c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a",
+ "ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6",
+ "82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73",
+ "2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6",
+ "16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6",
+ "78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3",
+ "0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa",
+ "f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3",
+ "2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b",
+ "227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f",
+ "1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc",
+ "5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200",
+ "dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6",
+ "02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8",
+ "64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f",
+ "f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a",
+ "e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e",
+ "e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935",
+ "85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74",
+ "aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0",
+ "7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c",
+ "de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145",
+ "aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f",
+ "c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0",
+ "76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb",
+ "72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4",
+ "64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91",
+ "12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89",
+ "60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444",
+ "a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a",
+ "b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414",
+ "fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49",
+ "34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b",
+ "3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0",
+ "ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469",
+ "022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3",
+ "e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd",
+ "94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8",
+ "31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21",
+ "91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989",
+ "d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1",
+ "d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399",
+ "7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0",
+ "58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723",
+ "27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff",
+ "3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc",
+ "eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38",
+ "c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a",
+ "8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051",
+ "24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca",
+ "5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4",
+ "e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677",
+ "bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1",
+ "d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce",
+ "50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347",
+ "0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91",
+ "1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209",
+ "e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659",
+ "b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381",
+ "72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56",
+ "c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7",
+ "c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f",
+ "6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972",
+ "3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe",
+ "c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e",
+ "8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be",
+ "28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8",
+ "2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc",
+ "66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8",
+ "f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0",
+ "8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc",
+ "3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979",
+ "06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29",
+ "c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d",
+ "4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108",
+ "898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45",
+ "ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4",
+ "3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267",
+ "95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d",
+ "227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb",
+ "5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813",
+ "7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc",
+ "062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29",
+ "f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc",
+ "ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16",
+ "c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1",
+ "15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c",
+ "89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7",
+ "e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a",
+ "8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa",
+ "da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e",
+ "f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc",
+ "11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5",
+ "b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a",
+ "ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3",
+ "29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc",
+ "3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d",
+ "3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff",
+ "07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb",
+ "b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4",
+ "7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc",
+ "1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902",
+ "106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e",
+ "0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08",
+ "521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816",
+ "1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406",
+ "5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4",
+ "b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d",
+ "bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d",
+ "65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900",
+ "ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06",
+ "e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01",
+ "3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0",
+ "fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94",
+ "951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02",
+ "8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492",
+ "16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2",
+ "c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c",
+ "72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb",
+ "c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077",
+ "c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727",
+ "f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd",
+ "348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c",
+ "5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0",
+ "2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403",
+ "b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391",
+ "64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8",
+ "0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605",
+ "f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9",
+ "3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d",
+ "d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe",
+ "cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe",
+ "98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1",
+ "771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3",
+ "c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb",
+ "8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b",
+ "1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef",
+ "af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253",
+ "29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec",
+ "a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a",
+ "0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473",
+ "b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837",
+ "74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a",
+ "3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1",
+ "58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d",
+ "9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9",
+ "b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537",
+ "1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7",
+ "4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2",
+ "695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338",
+ "a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15",
+ "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9",
+ "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
+}
+
+var hashes2X = []string{
+ "64",
+ "f457",
+ "e8c045",
+ "a74c6d0d",
+ "eb02ae482a",
+ "be65b981275e",
+ "8540ccd083a455",
+ "074a02fa58d7c7c0",
+ "da6da05e10db3022b6",
+ "542a5aae2f28f2c3b68c",
+ "ca3af2afc4afe891da78b1",
+ "e0f66b8dcebf4edc85f12c85",
+ "744224d383733b3fa2c53bfcf5",
+ "b09b653e85b72ef5cdf8fcfa95f3",
+ "dd51877f31f1cf7b9f68bbb09064a3",
+ "f5ebf68e7ebed6ad445ffc0c47e82650",
+ "ebdcfe03bcb7e21a9091202c5938c0a1bb",
+ "860fa5a72ff92efafc48a89df1632a4e2809",
+ "0d6d49daa26ae2818041108df3ce0a4db48c8d",
+ "e5d7e1bc5715f5ae991e4043e39533af5d53e47f",
+ "5232028a43b9d4dfa7f37439b49495926481ab8a29",
+ "c118803c922f9ae2397fb676a2ab7603dd9c29c21fe4",
+ "2af924f48b9bd7076bfd68794bba6402e2a7ae048de3ea",
+ "61255ac38231087c79ea1a0fa14538c26be1c851b6f318c0",
+ "f9712b8e42f0532162822f142cb946c40369f2f0e77b6b186e",
+ "76da0b89558df66f9b1e66a61d1e795b178ce77a359087793ff2",
+ "9036fd1eb32061bdecebc4a32aa524b343b8098a16768ee774d93c",
+ "f4ce5a05934e125d159678bea521f585574bcf9572629f155f63efcc",
+ "5e1c0d9fae56393445d3024d6b82692d1339f7b5936f68b062c691d3bf",
+ "538e35f3e11111d7c4bab69f83b30ade4f67addf1f45cdd2ac74bf299509",
+ "17572c4dcbb17faf8785f3bba9f6903895394352eae79b01ebd758377694cc",
+ "29f6bb55de7f8868e053176c878c9fe6c2055c4c5413b51ab0386c277fdbac75",
+ "bad026c8b2bd3d294907f2280a7145253ec2117d76e3800357be6d431b16366e41",
+ "386b7cb6e0fd4b27783125cbe80065af8eb9981fafc3ed18d8120863d972fa7427d9",
+ "06e8e6e26e756fff0b83b226dce974c21f970e44fb5b3e5bbada6e4b12f81cca666f48",
+ "2f9bd300244f5bc093ba6dcdb4a89fa29da22b1de9d2c9762af919b5fedf6998fbda305b",
+ "cf6bdcc46d788074511f9e8f0a4b86704365b2d3f98340b8db53920c385b959a38c8869ae7",
+ "1171e603e5cdeb4cda8fd7890222dd8390ede87b6f3284cac0f0d832d8250c9200715af7913d",
+ "bda7b2ad5d02bd35ffb009bdd72b7d7bc9c28b3a32f32b0ba31d6cbd3ee87c60b7b98c03404621",
+ "2001455324e748503aa08eff2fb2e52ae0170e81a6e9368ada054a36ca340fb779393fb045ac72b3",
+ "45f0761aefafbf87a68f9f1f801148d9bba52616ad5ee8e8ac9207e9846a782f487d5cca8b20355a18",
+ "3a7e05708be62f087f17b41ac9f20e4ef8115c5ab6d08e84d46af8c273fb46d3ce1aabebae5eea14e018",
+ "ea318da9d042ca337ccdfb2bee3e96ecb8f907876c8d143e8e44569178353c2e593e4a82c265931ba1dd79",
+ "e0f7c08f5bd712f87094b04528fadb283d83c9ceb82a3e39ec31c19a42a1a1c3bee5613b5640abe069b0d690",
+ "d35e63fb1f3f52ab8f7c6cd7c8247e9799042e53922fbaea808ab979fa0c096588cfea3009181d2f93002dfc11",
+ "b8b0ab69e3ae55a8699eb481dd665b6a2424c89bc6b7cca02d15fdf1b9854139cab49d34de498b50b2c7e8b910cf",
+ "fb65e3222a2950eae1701d4cdd4736266f65bf2c0d2e77968996eadb60ef74fb786f6234973a2524bdfe32d100aa0e",
+ "f28b4bb3a2e2c4d5c01a23ff134558559a2d3d704b75402983ee4e0f71d273ae056842c4153b18ee5c47e2bfa54313d4",
+ "7bb78794e58a53c3e4b1aeb161e756af051583d14e0a5a3205e094b7c9a8cf62d098fa9ea1db12f330a51ab9852c17f983",
+ "a879a8ebae4d0987789bcc58ec3448e35ba1fa1ee58c668d8295aba4eaeaf2762b053a677e25404f635a53037996974d418a",
+ "695865b353ec701ecc1cb38f3154489eed0d39829fc192bb68db286d20fa0a64235cde5639137819f7e99f86bd89afcef84a0f",
+ "a6ec25f369f71176952fb9b33305dc768589a6070463ee4c35996e1ced4964a865a5c3dc8f0d809eab71366450de702318e4834d",
+ "604749f7bfadb069a036409ffac5ba291fa05be8cba2f141554132f56d9bcb88d1ce12f2004cd3ade1aa66a26e6ef64e327514096d",
+ "daf9fa7dc2464a899533594e7916fc9bc585bd29dd60c930f3bfa78bc47f6c8439448043a45119fc9228c15bce5fd24f46baf9de736b",
+ "943ea5647a8666763084da6a6f15dcf0e8dc24f27fd0d9194805d25180fe3a6d98f4b2b5e0d6a04e9b41869817030f16ae975dd41fc35c",
+ "af4f73cbfc093760dfeb52d57ef45207bbd1a515f5523404e5d95a73c237d97ae65bd195b472de6d514c2c448b12fafc282166da132258e9",
+ "605f4ed72ed7f5046a342fe4cf6808100d4632e610d59f7ebb016e367d0ff0a95cf45b02c727ba71f147e95212f52046804d376c918cadd260",
+ "3750d8ab0a6b13f78e51d321dfd1aa801680e958de45b7b977d05732ee39f856b27cb2bcce8fbf3db6666d35e21244c2881fdcc27fbfea6b1672",
+ "8f1b929e80ab752b58abe9731b7b34eb61369536995abef1c0980d93903c1880da3637d367456895f0cb4769d6de3a979e38ed6f5f6ac4d48e9b32",
+ "d8469b7aa538b36cdc711a591d60dafecca22bd421973a70e2deef72f69d8014a6f0064eabfbebf5383cbb90f452c6e113d2110e4b1092c54a38b857",
+ "7d1f1ad2029f4880e1898af8289c23bc933a40863cc4ab697fead79c58b6b8e25b68cf5324579b0fe879fe7a12e6d03907f0140dfe7b29d33d6109ecf1",
+ "87a77aca6d551642288a0dff66078225ae39d288801607429d6725ca949eed7a6f199dd8a65523b4ee7cfa4187400e96597bfffc3e38ade0ae0ab88536a9",
+ "e101f43179d8e8546e5ce6a96d7556b7e6b9d4a7d00e7aade5579d085d527ce34a9329551ebcaf6ba946949bbe38e30a62ae344c1950b4bde55306b3bac432",
+ "4324561d76c370ef35ac36a4adf8f3773a50d86504bd284f71f7ce9e2bc4c1f1d34a7fb2d67561d101955d448b67577eb30dfee96a95c7f921ef53e20be8bc44",
+ "78f0ed6e220b3da3cc9381563b2f72c8dc830cb0f39a48c6ae479a6a78dcfa94002631dec467e9e9b47cc8f0887eb680e340aec3ec009d4a33d241533c76c8ca8c",
+ "9f6589c31a472e0a736f4eb22b6c70a9d332cc15304ccb66a6b97cd051b6ed82f8990e1d9bee2e4bb1c3c45e550ae0e7b96e93ae23f2fb8f63b309131e72b36cba6a",
+ "c138077ee4ed3d7ffa85ba851dfdf6e9843fc1dc00889d117237bfaad9aa757192f73556b959f98e6d24886ce48869f2a01a48c371785f12b6484eb2078f08c22066e1",
+ "f83e7c9e0954a500576ea1fc90a3db2cbd7994eaef647dab5b34e88ab9dc0b47addbc807b21c8e6dd3d0bd357f008471d4f3e0abb18450e1d4919e03a34545b9643f870e",
+ "3277a11f2628544fc66f50428f1ad56bcba6ee36ba2ca6ecdf7e255effc0c30235c039d13e01f04cf1efe95b5c2033ab72adda30994b62f2851d17c9920eadca9a251752dc",
+ "c2a834281a06fe7b730d3a03f90761daf02714c066e33fc07e1f59ac801ec2f4433486b5a2da8faa51a0cf3c34e29b2960cd0013378938dbd47c3a3d12d70db01d7d06c3e91e",
+ "47680182924a51cabe142a6175c9253e8ba7ea579ece8d9bcb78b1e9ca00db844fa08abcf41702bd758ee2c608d9612fed50e85854469cb4ef3038acf1e35b6ba4390561d8ae82",
+ "cec45830cd71869e83b109a99a3cd7d935f83a95de7c582f3adbd34e4938fa2f3f922f52f14f169c38cc6618d3f306a8a4d607b345b8a9c48017136fbf825aecf7b620e85f837fae",
+ "46fb53c70ab105079d5d78dc60eaa30d938f26e4d0b9df122e21ec85deda94744c1daf8038b8a6652d1ff3e7e15376f5abd30e564784a999f665078340d66b0e939e0c2ef03f9c08bb",
+ "7b0dcb52791a170cc52f2e8b95d8956f325c3751d3ef3b2b83b41d82d4496b46228a750d02b71a96012e56b0720949ca77dc68be9b1ef1ad6d6a5ceb86bf565cb972279039e209dddcdc",
+ "7153fd43e6b05f5e1a4401e0fef954a737ed142ec2f60bc4daeef9ce73ea1b40a0fcaf1a1e03a3513f930dd5335723632f59f7297fe3a98b68e125eadf478eb045ed9fc4ee566d13f537f5",
+ "c7f569c79c801dab50e9d9ca6542f25774b3841e49c83efe0b89109f569509ce7887bc0d2b57b50320eb81fab9017f16c4c870e59edb6c26620d93748500231d70a36f48a7c60747ca2d5986",
+ "0a81e0c547648595adca65623ce783411aac7f7d30c3ad269efafab288e7186f6895261972f5137877669c550f34f5128850ebb50e1884814ea1055ee29a866afd04b2087abed02d9592573428",
+ "6a7b6769e1f1c95314b0c7fe77013567891bd23416374f23e4f43e27bc4c55cfada13b53b1581948e07fb96a50676baa2756db0988077b0f27d36ac088e0ff0fe72eda1e8eb4b8facff3218d9af0",
+ "a399474595cb1ccab6107f18e80f03b1707745c7bf769fc9f260094dc9f8bc6fe09271cb0b131ebb2acd073de4a6521c8368e664278be86be216d1622393f23435fae4fbc6a2e7c961282a777c2d75",
+ "4f0fc590b2755a515ae6b46e9628092369d9c8e589e3239320639aa8f7aa44f8111c7c4b3fdbe6e55e036fbf5ebc9c0aa87a4e66851c11e86f6cbf0bd9eb1c98a378c7a7d3af900f55ee108b59bc9e5c",
+ "ed96a046f08dd675107331d267379c6fce3c352a9f8d7b243008a74cb4e9410836afaabe871dab6038ca94ce5f6d41fa922ce08aba58169f94cfc86d9f688f396abd24c11a6a9b0830572105a477c33e92",
+ "379955f539abf0eb2972ee99ed9546c4bbee363403991833005dc27904c271ef22a799bc32cb39f08d2e4ba6717d55153feb692d7c5efae70890bf29d96df02333c7b05ccc314e4835b018fec9141a82c745",
+ "e16cc8d41b96547ede0d0cf4d908c5fa393399daa4a9696e76a4c1f6a2a9fef70f17fb53551a8145ed88f18db8fe780a079d94732437023f7c1d1849ef69ad536a76204239e8ba5d97e507c36c7d042f87fe0e",
+ "a81de50750ece3f84536728f227208bf01ec5b7721579d007de72c88ee20663318332efe5bc7c09ad1fa8342be51f0609046ccf760a7957a7d8dc88941adb93666a4521ebe76618e5ddc2dd3261493d400b50073",
+ "b72c5fb7c7f60d243928fa41a2d711157b96aef290185c64b4de3dcfa3d644da67a8f37c2ac55caad79ec695a473e8b481f658c497edb8a191526592b11a412282d2a4010c90ef4647bd6ce745ebc9244a71d4876b",
+ "9550703877079c90e200e830f277b605624954c549e729c359ee01ee2b07741ecc4255cb37f96682dafcdbaade1063e2c5ccbd1918fb669926a67744101fb6de3ac016be4c74165a1e5a696b704ba2ebf4a953d44b95",
+ "a17eb44d4de502dc04a80d5a5e9507d17f27c96467f24c79b06bc98a4c410741d4ac2db98ec02c2a976d788531f1a4451b6c6204cef6dae1b6ebbcd0bde23e6fffb02754043c8fd3c783d90a670b16879ce68b5554fe1c",
+ "41d3ea1eaba5be4a206732dbb5b70b79b66a6e5908795ad4fb7cf9e67efb13f06fef8f90acb080ce082aadec6a1b543af759ab63fa6f1d3941186482b0c2b312f1151ea8386253a13ed3708093279b8eb04185636488b226",
+ "5e7cdd8373dc42a243c96013cd29df9283b5f28bb50453a903c85e2ce57f35861bf93f03029072b70dac0804e7d51fd0c578c8d9fa619f1e9ce3d8044f65d55634dba611280c1d5cfb59c836a595c803124f696b07ddfac718",
+ "26a14c4aa168907cb5de0d12a82e1373a128fb21f2ed11feba108b1bebce934ad63ed89f4ed7ea5e0bc8846e4fc10142f82de0bebd39d68f7874f615c3a9c896bab34190e85df05aaa316e14820b5e478d838fa89dfc94a7fc1e",
+ "0211dfc3c35881adc170e4ba6daab1b702dff88933db9a6829a76b8f4a7c2a6d658117132a974f0a0b3a38ceea1efc2488da21905345909e1d859921dc2b5054f09bce8eeb91fa2fc6d048ce00b9cd655e6aafbdaa3a2f19270a16",
+ "ddf015b01b68c4f5f72c3145d54049867d99ee6bef24282abf0eecdb506e295bacf8f23ffa65a4cd891f76a046b9dd82cae43a8d01e18a8dff3b50aeb92672be69d7c087ec1fa2d3b2a39196ea5b49b7baede37a586fea71aded587f",
+ "6ee721f71ca4dd5c9ce7873c5c04c6ce76a2c824b984251c15535afc96adc9a4d48ca314bfeb6b8ee65092f14cf2a7ca9614e1dcf24c2a7f0f0c11207d3d8aed4af92873b56e8b9ba2fbd659c3f4ca90fa24f113f74a37181bf0fdf758",
+ "689bd150e65ac123612524f720f54def78c095eaab8a87b8bcc72b443408e3227f5c8e2bd5af9bcac684d497bc3e41b7a022c28fb5458b95e8dfa2e8caccde0492936ff1902476bb7b4ef2125b19aca2cd3384d922d9f36dddbcd96ae0d6",
+ "3a3c0ef066fa4390ec76ad6be1dc9c31ddf45fef43fbfa1f49b439caa2eb9f3042253a9853e96a9cf86b4f873785a5d2c5d3b05f6501bc876e09031188e05f48937bf3c9b667d14800db62437590b84ce96aa70bb5141ee2ea41b55a6fd944",
+ "741ce384e5e0edaebb136701ce38b3d33215415197758ae81235307a4115777d4dab23891db530c6d28f63a957428391421f742789a0e04c99c828373d9903b64dd57f26b3a38b67df829ae243feef731ead0abfca049924667fdec49d40f665",
+ "a513f450d66cd5a48a115aee862c65b26e836f35a5eb6894a80519e2cd96cc4cad8ed7eb922b4fc9bbc55c973089d627b1da9c3a95f6c019ef1d47143cc545b15e4244424be28199c51a5efc7234dcd94e72d229897c392af85f523c2633427825",
+ "71f1554d2d49bb7bd9e62e71fa049fb54a2c097032f61ebda669b3e1d4593962e47fc62a0ab5d85706aebd6a2f9a192c88aa1ee2f6a46710cf4af6d3c25b7e68ad5c3db23ac009c8f13625ff85dc8e50a9a1b2682d3329330b973ec8cbb7bb73b2bd",
+ "167cc1067bc08a8d2c1a0c10041ebe1fc327b37043f6bd8f1c63569e9d36ded58519e66b162f34b6d8f1107ef1e3de199d97b36b44141a1fc4f49b883f40507ff11f909a017869dc8a2357fc7336ae68703d25f75710b0ff5f9765321c0fa53a51675c",
+ "cb859b35dc70e264efaad2a809fea1e71cd4a3f924be3b5a13f8687a1166b538c40b2ad51d5c3e47b0de482497382673140f547068ff0b3b0fb7501209e1bf36082509ae85f60bb98fd02ac50d883a1a8daa704952d83c1f6da60c9624bc7c99912930bf",
+ "afb1f0c6b7125b04fa2578dd40f60cb411b35ebc7026c702e25b3f0ae3d4695d44cfdf37cb755691dd9c365edadf21ee44245620e6a24d4c2497135b37cd7ac67e3bd0aaee9f63f107746f9b88859ea902bc7d6895406aa2161f480cad56327d0a5bba2836",
+ "13e9c0522587460d90c7cb354604de8f1bf850e75b4b176bda92862d35ec810861f7d5e7ff6ba9302f2c2c8642ff8b7776a2f53665790f570fcef3cac069a90d50db42227331c4affb33d6c040d75b9aeafc9086eb83ced38bb02c759e95ba08c92b17031288",
+ "0549812d62d3ed497307673a4806a21060987a4dbbf43d352b9b170a29240954cf04bc3e1e250476e6800b79e843a8bd8253b7d743de01ab336e978d4bea384eaff700ce020691647411b10a60acacb6f8837fb08ad666b8dcc9eaa87ccb42aef6914a3f3bc30a",
+ "3a263efbe1f2d463f20526e1d0fd735035fd3f808925f058b32c4d8788aeeab9b8ce233b3c34894731cd73361f465bd350395aebcabd2fb63010298ca025d849c1fa3cd573309b74d7f824bbfe383f09db24bcc565f636b877333206a6ad70815c3bef5574c5fc1c",
+ "3c6a7d8a84ef7e3eaa812fc1eb8e85105467230d2c9e4562edbfd808f4d1ac15d16b786cc6a02959c2bc17149c2ce74c6f85ee5ef22a8a96b9be1f197cffd214c1ab02a06a9227f37cd432579f8c28ff2b5ac91cca8ffe6240932739d56788c354e92c591e1dd76499",
+ "b571859294b02af17541a0b5e899a5f67d6f5e36d38255bc417486e69240db56b09cf2607fbf4f95d085a779358a8a8b41f36503438c1860c8f361ce0f2783a08b21bd7232b50ca6d35428335272a5c05b436b2631d8d5c84d60e8040083768ce56a250727fb0579dd5c",
+ "98ee1b7269d2a0dd490ca38d447279870ea55326571a1b430adbb2cf65c492131136f504145df3ab113a13abfb72c33663266b8bc9c458db4bf5d7ef03e1d3b8a99d5de0c024be8fabc8dc4f5dac82a0342d8ed65c329e7018d6997e69e29a01350516c86beaf153da65ac",
+ "41c5c95f088df320d35269e5bf86d10248f17aec6776f0fe653f1c356aae409788c938befeb67c86d1c8870e8099ca0ce61a80fbb5a6654c44529368f70fc9b9c2f912f5092047d0ffc339577d24142300e34948e086f62e23ecaca410d24f8a36b5c8c5a80e0926bc8aa16a",
+ "9f93c41f533b2a82a4df893c78faaaa793c1506974ba2a604cd33101713ca4adfd30819ffd8403402b8d40aff78106f3357f3e2c24312c0d3603a17184d7b999fc9908d14d50192aebabd90d05073da7af4be37dd3d81c90acc80e8333df546f17ab6874f1ec204392d1c0571e",
+ "3da5207245ac270a915fc91cdb314e5a2577c4f8e269c4e701f0d7493ba716de79935918b917a2bd5db98050dbd1eb3894b65fac5abf13e075abebc011e651c03cafb6127147771a5c8418223e1548137a89206635c26ca9c235ccc108dc25cf846e4732444bd0c2782b197b262b",
+ "96011af3965bb941dc8f749932ea484eccb9ba94e34b39f24c1e80410f96ce1d4f6e0aa5be606def4f54301e930493d4b55d484d93ab9dd4dc2c9cfb79345363af31ad42f4bd1aa6c77b8afc9f0d551bef7570b13b927afe3e7ac4de7603a0876d5edb1ad9be05e9ee8b53941e8f59",
+ "51dbbf2a7ca224e524e3454fe82ddc901fafd2120fa8603bc343f129484e9600f688586e040566de0351d1693829045232d04ff31aa6b80125c763faab2a9b233313d931903dcfaba490538b06e4688a35886dc24cdd32a13875e6acf45454a8eb8a315ab95e608ad8b6a49aef0e299a",
+ "5a6a422529e22104681e8b18d64bc0463a45df19ae2633751c7aae412c250f8fb2cd5e1270d3d0cf009c8aa69688ccd4e2b6536f5747a5bc479b20c135bf4e89d33a26118705a614c6be7ecfe766932471ad4ba01c4f045b1abb5070f90ec78439a27a1788db9327d1c32f939e5fb1d5ba",
+ "5d26c983642093cb12ff0afabd87b7c56e211d01844ad6da3f623b9f20a0c968034299f2a65e6673530c5980a532beb831c7d0697d12760445986681076dfb6fae5f3a4d8f17a0db5008ce8619f566d2cfe4cf2a6d6f9c3664e3a48564a351c0b3c945c5ee24587521e4112c57e318be1b6a",
+ "52641dbc6e36be4d905d8d60311e303e8e859cc47901ce30d6f67f152343e3c4030e3a33463793c19effd81fb7c4d631a9479a7505a983a052b1e948ce093b30efa595fab3a00f4cef9a2f664ceeb07ec61719212d58966bca9f00a7d7a8cb4024cf6476bab7fbccee5fd4e7c3f5e2b2975aa2",
+ "a34ce135b37bf3db1c4aaa4878b4499bd2ee17b85578fcaf605d41e1826b45fdaa1b083d8235dc642787f11469a5493e36806504fe2a2063905e821475e2d5ee217057950370492f5024995e77b82aa51b4f5bd8ea24dc71e0a8a640b0592c0d80c24a726169cf0a10b40944747113d03b52708c",
+ "46b3cdf4946e15a5334fc3244d6680f5fc132afa67bf43bfade23d0c9e0ec64e7dab76faaeca1870c05f96b7d019411d8b0873d9fed04fa5057c039d5949a4d592827f619471359d6171691cfa8a5d7cb07ef2804f6ccad4821c56d4988bea7765f660f09ef87405f0a80bcf8559efa111f2a0b419",
+ "8b9fc21691477f11252fca050b121c5334eb4280aa11659e267297de1fec2b2294c7ccee9b59a149b9930b08bd320d3943130930a7d931b71d2f10234f4480c67f1de883d9894ada5ed5071660e221d78ae402f1f05af47761e13fec979f2671e3c63fb0ae7aa1327cf9b8313adab90794a52686bbc4",
+ "cd6598924ce847de7ff45b20ac940aa6292a8a99b56a74eddc24f2cfb45797188614a21d4e8867e23ff75afd7cd324248d58fcf1ddc73fbd115dfa8c09e62022fab540a59f87c989c12a86ded05130939f00cd2f3b512963dfe0289f0e54acad881c1027d2a0292138fdee902d67d9669c0ca1034a9456",
+ "594e1cd7337248704e691854af0fdb021067ddf7832b049ba7b684438c32b029eded2df2c89a6ff5f2f2c311522ae2dc6db5a815afc60637b15ec24ef9541f1550409db2a006da3affffe548a1eaee7bd114e9b805d0756c8e90c4dc33cb05226bc2b393b18d953f8730d4c7ae693159cdba758ad28964e2",
+ "1f0d292453f04406ada8be4c161b82e3cdd69099a8637659e0ee40b8f6da46005cfc6085db9804852decfbe9f7b4dda019a7112612895a144ed430a960c8b2f5458d3d56b7f427cee6358915aee7146278aed2a0296cdd929e4d21ef95a3adf8b7a6beba673cdccdbdcfb2474711732d972ad054b2dc64f38d",
+ "b65a72d4e1f9f9f75911cc46ad0806b9b18c87d105332a3fe183f45f063a746c892dc6c4b9181b1485b3e3a2cc3b453eba2d4c39d6905a774ed3fb755468beb190925ecd8e57ecb0d985125741650c6b6a1b2a3a50e93e3892c21d47ed5884eed83aa94e1602288f2f49fe286624de9d01fcb54433a0dc4ad70b",
+ "705ce0ffa469250782aff725248fc88fe98eb76659e8407edc1c4842c9867d61fe64fb86f74e980598b92bc213d06f337bd5654fc28643c7ba769a4c31563427543c00808b627a19c90d86c322f33566ce020121cc322229c3337943d46f68ef939d613dcef0077269f88151d6398b6b009abb763410b154ad76a3",
+ "7fa881ce87498440ab6af13854f0d851a7e0404de33896999a9b3292a5d2f5b3ad033530c558168fe5d2fdb9b89a2354c46cf32a0e612afc6c6485d789511bfef26800c74bf1a4cfbe30bda310d5f6029c3dccdedb6149e4971274e276dccfabd63bc4b9955e8303feb57f8a688db55ecb4b33d1f9fe1b3a8ba7ac32",
+ "23a98f71c01c0408ae16843dc03be7db0aeaf055f951709d4e0dfdf64fffbffaf900ee592ee10929648e56f6c1e9f5be5793f7df66453eb56502c7c56c0f0c88da77abc8fa371e434104627ef7c663c49f40998dbad63fa6c7aa4fac17ae138d8bbe081f9bd168cd33c1fbc92fa35ed687679f48a64b87db1fe5bae675",
+ "7b8970b6a33237e5a7bcb39272703edb92285c55842b30b9a48834b1b507cc02a6764739f2f7ee6ae02a7b715a1c455e59e8c77a1ae98abb10161853f1234d20da99016588cd8602d6b7ec7e177d4011edfa61e6b3766a3c6f8d6e9eac893c568903eb6e6aba9c4725774f6b4343b7acaa6c031593a36eef6c72806ff309",
+ "f7f4d328ba108b7b1de4443e889a985ed52f485f3ca4e0c246aa5526590cbed344e9f4fe53e4eea0e761c82324649206ca8c2b45152157d4115e68c818644b03b65bb47ad79f94d37cb03c1d953b74c2b8adfa0e1c418bda9c518ddcd7050e0f149044740a2b16479413b63fc13c36144f80c73687513dca761ba8642a8ae0",
+ "2d7dc80c19a1d12d5fe3963569547a5d1d3e821e6f06c5d5e2c09401f946c9f7e13cd019f2f9a878b62dd850453b6294b99ccaa068e542993524b0f63832d48e865be31e8ec1ee103c718340c904b32efb69170b67f038d50a3252794b1b4076c0620621ab3d91215d55ffea99f23d54e161a90d8d4902fda5931d9f6a27146a",
+ "77dff4c7ad30c954338c4b23639dae4b275086cbe654d401a2343528065e4c9f1f2eca22aa025d49ca823e76fdbb35df78b1e5075ff2c82b680bca385c6d57f7ea7d1030bb392527b25dd73e9eeff97bea397cf3b9dda0c817a9c870ed12c006cc054968c64000e0da874e9b7d7d621b0679866912243ea096c7b38a1344e98f74",
+ "83bed0d556798f2b419f7056e6d3ffada06e939b95a688d0ec8c6ac5ea45ab73a4cf01043e0a170766e21395f27ab4b78c435f5f0dfe6e93ab80df38610e41158429ddf20296f53a06a017723359fe22dc08b5da33f0800a4fe50118e8d7eab2f83a85cd764bf8a166903bd0e9dcfeeceba44ff4ca4439846458d31ea2bb564645d1",
+ "ea12cf5a113543e39504123036f15a5bafa9c555562469f99cd29996a4dfaaab2a34b00557ccf15f37fc0cc1b3be427e725f2cd952e50af7970dda9200cd5ce252b1f29c40067fea3027ed686190803b59d834179d1b8f5b55abe55ad174b2a1188f7753ec0ae2fc01316e7d498b68ee3598a0e9baaaa664a60f7fb4f90edbed494ad7",
+ "55266358332d8d9e68bd13432088beadf95833aab67a0eb3b10650414255f299e2670c3e1a5b2976159a46c72a7ce57d59b7be14c15798e09ed50fa312a431b0264d7a1396aa6168bde897e208ece53d2cfc83786113b1e6eac5e9bb98984abb6c8d64eebb991903254abc650c999bb9958a5d7937434b869bc940e21b9dc1cc8982f2ba",
+ "4d6104ded730aefe02873f4c741232c8234a6d66d85393aff57fbf56ba6347666988dfc4d58f3cc895a0da598822edeee4533d24ec0ee292fd5e1ad04898ffbc1ff4bef14dec220babcb0f28fffe32a6e2c28aaaac16442bf4feb02917d18bb3a415d84fa9358d5a9852688d846c92271911f934181c30f82434d915f93f155a1ffbf0b125",
+ "eb5f579a4c476af554aac11e5719d378549497e613b35a929d6f36bb8831d7a466aa76de9be24ebb55543f1c13924f64cfd648a5b3fa90387315c16174dbf1e9a183c196d9bb8f84af65f1f8212429aadc11ef2426d07d4716062b85c8d5d2dff8e21b9e62b7fa7dbd57d72633054b464fb28583a56ca13ccc5ddc74dae942492f31731e7046",
+ "ebddec3dcaf18063e45a76ebeac39af85a1adc2818881ccce48c106288f5988365cca2b4b1d7f037322da46840f42bebdcbc7193838d426e101087d8cea03aaff743d573eb4f4e9a71a2c884390769a6503874125d194bee8d46a3a0d5e4fcf28ff8465887d8e9df771d70157e75df3642b331d2778ceb32ceba868640171ab7a5d22eede1ee44",
+ "26d87ec70b57691e3bb359633d3ddba17f029d62cdfe977f5fd42274d79b444a32494d1c01e9f72d03cce78c806df96e93ea78da3a054209924ed765edc4d570f66168dc25ee3114e4017e387440349c8f0a94804761c3055f88e4fda2a49b860b1486a9609095f6250f268b6a4d1aecc03a505632ebf0b9dc22d0755a736faf7ad7000858b5864b",
+ "3880f5cc2d08fa70ef44b1f263fcf534d062a298c1bd5ee2eee8c3265806c4ce50b004f3a1fc1fa5b024aaac7f528c023c8181f67c6e1c357425dc4d573bd46b93a542afa3a19bdb140a2ce666e1a01f5c4d2dcd681fa9f5839b797813c394738d5ee4971386c12c7c117d17c7bec324b760aa30cda9ab2aa850284ba6fa97946f710f02449d1883c6",
+ "3317d2f452105dd3f4a96f9257af8285a80be58066b50f6f54bd633749b49f6ab9d57d45652d2ae852a2f6940cd5ec3159dd7f333358b12f502325df38843508faf7e246352d201280babd90b14fbf7722641c3601d0e458474439973c611bb5502fd0eb3078f87124ca7e1a016fcb6cfeff65f6a565985aca7122cfa8c5a11da0cb47797c5132333179",
+ "f2c5c955d0224e784a46b9125f8fef8a5e1271e145eb08bbbd07ca8e1cfc848cef14fa3b36221ac62006403dbb7f7d77958ccc54a8566c837858b809f3e310ace8ca682515bc655d2a397cab238a663b464d511f02dc5d033dad4cb5e0e519e94a54b62a3896e460ec70e5716b5921bf8396aa86a60123e6287e34570bb01bdc602e113670bf498af2ff10",
+ "180e275205691a83630cf4b0c7b80e6df8fad6ef1c23ba8013d2f09aef7abade1827f23af230de90676240b4b3b0673f8afdea0327330055041741f65560d90348de696d34ca80dfe8afae582fe4879d4594b80e9408fb53e800e01ca58552b905c365e7f1416e51c080f517d6bbd30e64ae1535d59decdc76c6624d737868f49f2f719da39ba1344d59eab9",
+ "c517a84e4631a7f65ace170d1e5c2fdb259841535d88da323e68c0883e6af7b041cfe05908815a5a9d1b14fa712c2c16fadcf1ca54d3aa954d411240df331b2aebdfb65aced84d0b8aace56ec0aa7c13ec7d75ca883b6bcf6db74c9e98463c484a8262684f29910373430651f90ecffe18b072170e61ee58de20e2a6ff67b3ab00fccbb80af943f20b56b98107",
+ "d1a56a5ee990e02b84b5862fde62f69ec07567be2d7ccb769a461c4989d11fdda6c945d942fb8b2da795ed97e43a5b7dbdde7f8fd2ff7154544336d5c50fb7380341e660d4898c7fbc39b2b782f28defac6873523c7c1de8e52c65e4395c686ba483c35a220b0416d46357a063fa4c33fa9c52d5c207a1304ae141c791e62ba6a7374ed922b8dd94079b72b69302",
+ "4720b88d6bfb1ab43958e26827730d852d9ec30173ebd0fe0d273edcece2e788558984cd9306fe5978086a5cb6d37975755d2a3daeb16f99a8a11544b8247a8b7ed5587afc5bea1daf85dcea5703c5905cf56ae7cc76408ccabb8fcc25cacc5ff456db3f62fa559c45b9c71505eb5073df1f10fc4c9060843f0cd68bbb4e8edfb48d0fd81d9c21e53b28a2aae4f7ba",
+ "f4639b511db9e092823d47d2947efacbaae0e5b912dec3b284d2350b9262f3a51796a0cd9f8bc5a65879d6578ec24a060e293100c2e12ad82d5b2a0e9d22965858030e7cdf2ab3562bfa8ac084c6e8237aa22f54b94c4e92d69f22169ced6c85a293f5e16bfc326153bf629cdd6393675c6627cd949cd367eef02e0f54779f4d5210197698e4754a5fe490a3a7521c1c",
+ "3d9e7a860a718565e3670c29079ce80e381969fea91017cfd5952e0d8a4a79bb08e2cd1e26161f30ee03a24891d1bfa8c212861b51618d07429fb48000ff87ef09c6fca526567777e9c076d58a642d5c521b1caa5fb0fb3a4b8982dc14a444732b72b239b8f01fc8ba8ee86b3013b5d3e98a92b2aeaecd4879fca5d5e9e0bd880dbfffa6f96f94f3998812aac6a714f331",
+ "4d9bf551d7fd531e7482e2ec875c0651b0bcc6caa738f7497befd11e67ae0e036c9d7ae4301cc3c7906f0d0e1ed4738753f414f9b3cd9b8a71176e325c4c74ce020680ecbfb146889597f5b40487e93f974cd866817fb9fb24c7c7c16177e6e120bfe349e83aa82ba40e59e917565788658a2b254f25cf99bc65070b3794cea2259eb10e42bb54852cba3110baa773dcd70c",
+ "b91f65ab5bc059bfa5b43b6ebae243b1c46826f3da061338b5af02b2da76bb5ebad2b426de3c3134a633499c7c36a120369727cb48a0c6cbab0acecdda137057159aa117a5d687c4286868f561a272e0c18966b2fec3e55d75abea818ce2d339e26adc005c2658493fe06271ad0cc33fcb25065e6a2a286af45a518aee5e2532f81ec9256f93ff2d0d41c9b9a2efdb1a2af899",
+ "736f6e387acb9acbee026a6080f8a9eb8dbb5d7c54ac7053ce75dd184b2cb7b942e22a3497419ddb3a04cf9e4eb9340a1a6f9474c06ee1dcfc8513979fee1fc4768087617fd424f4d65f54782c787a1d2de6efc81534343e855f20b3f3589027a5436201eee747d45b9b8375e4294d72ab6a52e04dfbb2914db92ee58f134b026527ed52d4f794459e02a43a17b0d51ea69bd7f3",
+ "9242d3eb31d26d923b99d66954cfade94f25a18912e6356810b63b971ae74bb53bc58b3c01424208ea1e0b1499936daea27e63d904f9ed65fdf69de40780a3027b2e89d94bdf214f585472613ce328f628f4f0d56217dfb53db5f7a07f54c8d71db16e27de7cdb8d23988837b49b65c12f1771d979e8b192c9f4a16b8d9fba917bcf74ce5a82aac2075608ba6c2d485fa59864b9de",
+ "5da68704f4b592d41f08aca08f62d85e2e2466e5f3be010315d11d113db674c4b98764a509a2f5aacc7ae72c9deff2bcc42810b47f64d429b35745b9efff0b18c58653461e968aaa3c2c7fc455bc5771a8f10cd184be831040df767201ab8d32cb9a58c89afbebecb524502c9b940c1b838f8361bbcde90d272715017f67609ea39b20fac985332d82daaa023999e3f8bfa5f3758bb8",
+ "71ea2af9c8ac2e5ae44a176662882e01027ca3cdb41ec2c6785606a07d7231cd4a2bded7155c2feef3d44d8fd42afa73265cef826f6e03aa761c5c51d5b1f129ddc27503ff50d9c2d748322df4b13dd5cdc7d46381528ab22b79b0049011e4d2e57fe2735e0d58d8d56e92c75dbeac8c76c4239d7f3f24fb56697593b3e4afa6671d5bbc96c079a1c154fe20212ade67b05d49ceaa7a84",
+ "1d133170582fa4bff59a21953ebbc01bc202d43cd79c083d1f5c02fa15a43a0f519e36acb710bdabac880f04bc003800641c2487930de9c03c0e0deb347fa815efca0a38c6c5de694db698743bc955581f6a945deec4ae988ef7cdf40498b77796ddea3fae0ea844891ab751c7ee20917c5a4af53cd4ebd82170078f41ada2795e6eea17593fa90cbf5290a1095e299fc7f507f360f187cd",
+ "5ec4ac45d48fc15c72471d795066bdf8e99a483d5fdd599511b9cdc408de7c0616491b73924d0266da34a495331a935c4b8884f57d7ad8cce4cbe586875aa52482215ed39d7626cce55d50349c7767981c8bd6890f132a196184247343566fc972b86fe3c5369d6a6519e9f07942f0522b77ad01c751dcf7defe31e471a0ec00963765dd8518144a3b8c3c978ad108056516a25dbe3092e73c",
+ "0d5e74b78290c689f2b3cfea45fc9b6a84c822639cd438a7f05c07c374adced42cdc12d2a9233a4ffe80307efc1ac13cb04300e165f8d90dd01c0ea955e7657332c6e86ad6b43e78ba4c13c675aed83192d8427866fb6484e6a3071b2369a46fba9005f31232da7ffec7952f831aaaddf63e225263531c2cf387f8cc14fa856c8795137142c3a52ffa69b8e30ebc88ce3bbc227597bcc8dddd89",
+ "a0fe36f983259921dc2fa7d89002b3066241d63bfc2448caf7e10522a35562be0bfedc3dce49cfce2e614a04d4c64cfc0ab898873a7fc26928dc1927c009d12f6f9b7a278205d3d0057604f4ac746f8b9287c3bc6b929832bf253b6586192ac43fdd29ba585dbd9059aab9c6ff6000a7867c67fec1457b733f6b620881166b8fed92bc8d84f0426002e7be7fcd6ee0abf3755e2babfe5636ca0b37",
+ "1d29b6d8eca793bb801becf90b7d7de215b17618ec32340da4bac707cdbb58b951d5036ec02e105d83b5960e2a72002d19b7fa8e1128cc7c5049ed1f76b82a59eac6ed09e56eb73d9ade38a6739f0e07155afa6ec0d9f5cf13c4b30f5f9a465b162a9c3ba04b5a0b3363c2a63f13f2a3b57c590ec6aa7f64f4dcf7f1582d0ca157eb3b3e53b20e306b1f24e9bda87397d413f01b453ceffeca1fb1e7",
+ "6a2860c110cd0fc5a19bcaafcd30762ee10242d34739638e716bd89fd537ea4dc630e6f85d1bd88a25ad3892ca554c232c9830bd56980c9f08d378d28f7fa6fa7df4fcbf6ad98b1adfff3ec1f63310e50f920c99a5200b8e64c2c2ca249399a149942261f737d5d72da949e914c024d57c4b639cb89990fed2b38a37e5bcd24d17ca12dfcd36ce04691fd03c32f6ed5de2a2191ed7c826375ba81f78d0",
+ "7132aa291ddc9210c60dbe7eb3c19f9053f2dd74742cf57fdc5df98312adbf4710a73245de4a0c3b24e21ab8b466a77ae29d15500d5142555ef3088cbccbe685ed9119a10755148f0b9f0dbcf02b2b9bcadc8517c88346ea4e78285e9cbab122f824cc18faf53b742a87c008bb6aa47eed8e1c8709b8c2b9adb4cc4f07fb423e5830a8e503ab4f7945a2a02ab0a019b65d4fd71dc364d07bdc6e637990e3",
+ "3e664da330f2c6007bff0d5101d88288aaacd3c07913c09e871cce16e55a39fde1ce4db6b8379977c46cce08983ca686778afe0a77a41baf447854b9aa286c398c2b83c95a127b053101b6799c1638e5efd67273b2618df6ec0b96d8d040e8c1ee01a99b9b5c8fe63fea2f749e6c90d31f6fae4e1469ac09884c4fe1a8539acb313f42c941224a0e79c059e18affc2bcb6724975c436f7bf949ebdd8aef51c",
+ "7a6ea63a271eb49470f5ce77519ed61ae9b2f1be07a96855726bc3df1d0723af3a703fdfc2e739c9d31d25814daf661a23558b50982e66ee37ad880f5c8f11c8130fac8a5d0250583700d5a324894fae6d61993f6bf9327214f8674649f355b23fd634940b2c467973a839e659169c773119919f5b81ee171edb2e5f6940d7551f9e5a70625d9ea88711ad0ed8ab2da720ad358bef954456cb2d5636425717c2",
+ "c5106bbda114168c449172e49590c7eeb827fa4e1a2a7a87a3c1f721a9047d0c0a50fbf244731be1b7eb1a2ef30f5ae846a9f38f0df44f32af61b68dbdcd0226e741dfb6ef81a2503691af5e4b3171f48c59ba4ef91eba344b5b697f261df7bbbb734ca6e6daebaa4a179feb17002823281b8534d55a6531c59305f6e3fd3fa63b747bcf0deb654c392a02fe687a269effb1238f38bcaea6b208b221c45fe7fbe7",
+ "597716a5ebeebc4bf524c15518816f0b5dcda39cc833c3d66b6368ce39f3fd02ceba8d12072bfe6137c68d3acd50c849873150928b320b4fbc31c1456679ea1d0acaeeabf666d1f1bad3e6b9312c5cbdecf9b799d3e30b0316bed5f41245107b693366accc8b2bcef2a6be54209ffabc0bb6f93377abdcd57d1b25a89e046f16d8fd00f99d1c0cd247aafa72234386ae484510c084ee609f08aad32a005a0a5710cb",
+ "0771ffe789f4135704b6970b617bae41666bc9a6939d47bd04282e140d5a861c44cf05e0aa57190f5b02e298f1431265a365d29e3127d6fccd86ec0df600e26bcdda2d8f487d2e4b38fbb20f1667591f9b5730930788f2691b9ee1564829d1ada15fffc53e785e0c5e5dd11705a5a71e390ca66f4a592785be188fefe89b4bd085b2024b22a210cb7f4a71c2ad215f082ec63746c7367c22aedb5601f513d9f1ffc1f3",
+ "be6556c94313739c115895a7bad2b620c0708e24f0390daa55521c31d2c6782acf41156271238885c367a57c72b4fe999c160e804ad58d8e565edbce14a2dd90e443eb80626b3eab9d7ab75d6f8a062d7ca89b7af8eb292c98eaf87ad1dfd0db103d1bb6188bd7e7a63502153cf3ce23d43b60c5782602bac8ad92fb2324f5a79453898c5de18415639ecc5c7974d3077f76fc1df5b956723bb19a624d7ea3ec13ba3d86",
+ "4bc33729f14cd2f1dc2ff459abee8f6860dda1062845e4adab78b53c835d106bdfa35dd9e77219eaef403d4e80488ca6bd1c93dd76ef9d543fbb7c8904dccc5f71509a6214f73d0f4e467c3e038ea639b29e7fc442ee29f57117740576188ada15a739827c647a46b0271817ab235c023c30c90f2115e5c90cd8501e7b286962fc66ffc3fe7e8978746168314908a41998bd83a1eeffda9d714b864f4d490fdeb9c7a6edfa",
+ "ab12faea205b3d3a803cf6cb32b9698c32301a1e7f7c6c23a20174c95e98b7c3cfe93fffb3c970face8f5751312a261741141b948d777b8a2ea286fe69fc8ac84d34116a4674bb09a1a0b6af90a748e511749de4697908f4acb22be08e96ebc58ab1690acf73914286c198a2b57f1dd70ea8a52325d3045b8bdfe9a09792521526b7564a2a5fcd01e291f1f8894017ce7d3e8a5dba15332fb410fcfc8d62195a48a9e7c86fc4",
+ "7d421e59a567af70594757a49809a9c22e07fe14061090b9a041875bb77933deae36c823a9b47044fa0599187c75426b6b5ed94982ab1af7882d9e952eca399ee80a8903c4bc8ebe7a0fb035b6b26a2a013536e57fa9c94b16f8c2753c9dd79fb568f638966b06da81ce87cd77ac0793b7a36c45b8687c995bf4414d28289dbee977e77bf05d931b4feaa359a397ca41be529910077c8d498e0e8fb06e8e660cc6ebf07b77a02f",
+ "0c18ab727725d62fd3a2714b7185c09faca130438eff1675b38beca7f93a6962d7b98cb300ea33067a2035cdd694348784aa2eda2f16c731eca119a050d3b3ce7d5c0fd6c234354a1da98c0642451922f670984d035f8c6f35031d6188bbeb31a95e99e21b26f6eb5e2af3c7f8eea426357b3b5f83e0029f4c4732bca366c9aa625748297f039327c276cd8d9c9bf692a47af098aa50ca97b99961bef8bc2a7a802e0b8cfdb84319",
+ "92d5909d18a8b2b9971cd1627b461e98a74ba377186a6a9df5bd133635250b300abccb2254cacb775df6d99f7c7d0952653c28e6909b9f9a45adce691f7adc1afffcd9b06e49f775364cc2c62825b9c1a86089080e26b57e732aac98d80d009bfe50df01b95205aa07ed8ec5c873da3b92d00d53af825aa64b3c634c5ece40bff152c331222d3453fd92e0ca17cef19ecb96a6eed4961b627aca48b12fecd091754f770d52ba861546",
+ "802f22e4a388e874927fef24c797408254e03910bab5bf372320207f8067f2b1ea543917d4a27df89f5bf936ba12e04302bde23119533d0976beca9e20cc16b4dbf17a2ddc44b66aba76c61ad59d5e90de02a88327ead0a8b75463a1a68e307a6e2e53ecc1986274b9ee80bc9f3140671d5285bc5fb57b281042a8978a1175900c6073fd7bd740122956602c1aa773dd2896674d0a6beab24454b107f7c847acb31a0d332b4dfc5e3f2f",
+ "3844fe65db11c92fb90bf15e2e0cd216b5b5be91604baf3b84a0ca480e41ecfaca3709b32f8c6e8761406a635b88eec91e075c48799a16ca08f295d9766d74475c47f3f2a274eae8a6ee1d191a7f37ee413a4bf42cad52acd5564a651715ae42ac2cddd52f819c692ecdef52ecb763270322cdca7bd5aef71428fa73e844568b96b43c89bf1ed42a0abf209ffad0eeec286c6f141e8af073ba4adfbbdeda253752ae36c9957dfc905b4c49",
+ "329377f7bf3c8d74991a7d61b0cf39baff5d485d79751b0d5ad017d23bec570fb19810105bab79ab5acb102ab972165224d4ec888ec7de5148077fa9c1bb6820e0d91ae4e2591a21fec2f820606ce4bafc1e377f8dc3a5bd1a9e2772a57abccd0b757164d768872c91d02789545ab5b203f688d71dd08522a3fd2f5bcd7df507aebf1ca27ddff0a82afb7aa9c180008f49d1325adf97d047e77238fc75f56356de4e87d8c961575c9f6362c9",
+ "f7f269929b0d71ea8eef7120e55ccba691c582dd534692abef35c0fe9dec7dae973cd9702e5ad420d278fe0e653fdcb22fdcb63148109ec7e94f2d0750b28157dd1764376ae10fdb0a4aef3b304bd82793e0595f941226a2d72abbc929f53134dc495b0d65ced409914f94c2523f3dfbbdeeac84ae247ab5d1b9ea33dce1a808885a55be1f3683b46f4be73d9b62eec2585f690056858dfc427aabf591cd276724885bcd4c00b93bb51fb7484d",
+ "ac022309aa2c4d7fb628255b8b7fb4c3e3ae64b1cb65e0de711a6def1653d95d8088871cb8905fe8ae76423604988a8f77589f3f776dc1e4b30dbe9dd262b2187db02518a132d219bd1a06ebac13132b5164b6c420b37dd2ccee7d69b3b7fa12e54f0a53b853d490a68379ea1fa2d79762830ffb71bf86aab506b51f85c4b6a41b69325c7d0c7aa85b93b7144489d213e8f33dbb879fce22849865337b620b155cb2d2d36a68832889e30194d36d",
+ "d009c2b78a8f02e5e5dbb586ef71fc324b375092e15913ca1a5bfd22d516baadb96867bee3562e77c4a4852344a1a76c30728be5e22400b4cc41711f66754c246a520498d8c24f0205b9c873748dbeb67fe1ad099ad04cf89f4b517f0aa481136d9f6de2d727df01c6aa4099da59d4382b51e25fd47c33d9842c32b62331e50794bfe8b61b3ba9de1b8b704779c6d65edff3af00f121ab4a7ea384edabe47c6d0098a48991f387ca4444135ec59d46",
+ "c00bab36cce69899817d1425016d222d7303197ed3e3fdcac744705e7f178a1ac745968900f69299163e19b3161f3e0a4cc55aa2e4e71e0ee6ac427d1f4d14e063f68d303ddfbb18118335cfa7a6a90d99c38319ee76f7a884846a9e0b68030bf28e78bfbd56359b9368842814da42b04cb0e307d5d846dc22f049147bae31b9a956d17676a8cc348dafa3cabc2007a30e730e3894dddf9999fb8819086311f0703e141613ed6dcd7af8510e2dc435b0",
+ "c9789152a9fc29698d49ed95f09bd11b75f18a8c5615a73dbe54ae5e550027fd0ae6a8b60667040c1b12de3d1ee3f6bf061c78c951a3210effc912e19f482dd4de152063c588c44903bc11761706fd935afa040df085b08144d83d0dde32b46ab52f4fae98ac116c7ff11d7f553450c2e37b9c5f0b1dd9e0b8640a24cba6f2a5246c41f197f46e3dc8a29131c79bef3351c6e277a0a34442274d546ccd058891277473d668420f121750d19cd684267405",
+ "06a15a0731ce52557e368bcbaa11ef3399299e36fb9f2eda6e5726907c1d29c5c6fc581405ba48c7e2e522206a8f128d7c1c939d1132a00bd7d6366aa82724e968964eb2e373563f607dfa649590dcf5589114df69da5547fef8d1604cc4c6de1ed5783c8746918a4dd31168d6bc8784cd0c769206bd803d6ca8557b66748770402b075ef44b38157d4c0da7c6281725a2065d087b1f7b23455fa673bdeeba45b983311c44eabe9ef4b7bde3420ae9881863",
+ "d08aacef2d7a41aec09473bd8a44f628e15addb7b9e5b77a1e09c8ab4942f379a0bfcb324d580b774666f18ae78dd36710824ff12393f059068fe4b559c53662c2b0e6c69e23785c8f32554e837ec1714bee902e60737b639dd933af4f68cb9d7de77e1f3b28e5b122891afce62b79acd5b1ab4ba411662cc77d806449e69c5a45a143b742d98ac84a0826d68433b9b700ace6cd472ba2d58a90847f42ce9c43f38ffc017db4bf40450b2eee1f4594dc740c0f",
+ "6a6058b0a498b7ea76a93c646eb9b8629f0cba4a0c726420c5f67ba9b0412cade356abdf0a4fb94384bad32ce0d5dd9e23dcaae1d6f28ff8683616b30f1392890c67b3a2c04b360893b801f127e527e4da82e239f4c878da13f4a4f1c76db07190e77ec123995168102fb274434a2d1e12913b9b5cbab4aacaad2bd89d88b3ca2b8e60dacf7c22c9379097ff60880f552e320ca3b571994f52534470feee2b39e0dadb5cd88257a3e459a4cc6f12f17b8d54e1bb",
+ "adeced01fc5671531cbb45679f5ddd42b3a95151677b6125aaf6f5e8f82fbabaa5ecf7c3552c2458587224f0042870f178f5fca5465250e75d71352e652eeed23cdb7f915f5ebb44099b6db116ca1be45530ac8ed32b7f161d60ed4397ad3d7d649ae6bf75ca5bec891d8e595605be9764f3a03965e1fe0eaffbf212e3df4f0fa35e08ff9d0091e6d4ac4748edfe43b611085a6ffec163014655fdd839fd9e81b63b1fa8cae4ec335ec343289758e389a79ceedfae",
+ "d014592f3a83ba40af366f137c674724916c3cdd3f6cf9d4c5c7c8d6d51ebf26e315e2c12b3546be56fb52382904046ecbd2f5b883aa4ff473de6f0c26ab862c3fa34bf3d880cc1911ce39a4088c6617c179dc5faf68a2c488bbde12d67b50f73abcfab0e3b062e68c95363e11f5f1de8ec36ed01ea21442518089045df67d346135283ad5b3fff80cf57f20876849f6db9fa139728358415a90610f69ec720fc92d8234e3e122551e9df2c644c4a2c4e3734d07de8e",
+ "c0d0c37838873ba8757d6e41b409605043bc1635edcd731219587676d94217e9f0ab44b71de25000661ce7303b7015f45e6eaa7b7ebef92b8f4a34c902c908d2172185505fa33aca5a41be83079316cdfdd430fc2c45f505f85d867e6d516f7e1bf19c001d9f43018968aab65ec031b3801399231c83ec9e622dab5629922a6b424cab938c135ff7310501c2c02971bfd2f577e25904d1a618baf0859f77f4e8b1d0cde9544e95ec52ff710c0672fdb3d891feeea2b017",
+ "7022e7f00902219ba97baa0e940e8ac7727f58955aa068c29680fac4a16bcd812c03eeb5adbcfe867a7f7c6b5d89f4641adb9173b76a1a8438866f9b4f640ce2aedf5f1080c890bcf515b4be4e3e512352f1e5323c62ec46cb73f3d71be8235fee55a154763f7c3f9aeb61ffd28f4cd93d3310f608e2133586bf1ab3f102de96f64c68a4668de8acb2a76a7ce0cddddc8fa3df5e9d230823da16ed9ebb402d36e38e6e018795e5a71517ecab5f9ca472b9ced8ff69d2d195",
+ "acaf4baf3681ab865ab9abfae41697141ead9d5e98523c2e0e1eeb6373dd15405242a3393611e19b693cabaa4e45ac866cc66663a6e898dc73095a4132d43fb78ff7166724f06562fc6c546c78f2d5087467fcfb780478ec871ac38d9516c2f62bdb66c00218747e959b24f1f1795fafe39ee4109a1f84e3f82e96436a3f8e2c74ef1a665b0daaa459c7a80757b52c905e2fb4e30c4a3f882e87bce35d70e2925a1671205c28c89886a49e045e31434abaab4a7aed077ff22c",
+ "84cb6ec8a2da4f6c3b15edf77f9af9e44e13d67acc17b24bd4c7a33980f37050c0301ba3aa15ad92efe842cd3ebd3636cf945bb1f199fe0682037b9dacf86f162dadabfa625239c37f8b8db9901df0e618ff56fa62a57499f7ba83baebc085eaf3dda850835520344a67e09419368d81012168e5de5ea45158397af9a5c6a1657b26f319b66f816cd2c28996547d697e8df2bb163ccb9dda4d6691dffd102a13667ab9cde60ffbfb872187d9c425a7f67c1d9fffff9276ed0aeb",
+ "6a52c9bbbba454c14540b2be58230d78ecbeb391646a0c6fcce2f789086a78364b81ae85d5396d7cfa8b46bda41e3083ec5cf7b4c47dc601c8a697df52f557defca248506dbebab25657f5a561d09625b7f4b2f0119a12beeac087efc9d350a735c35d2431c1da7dda99befb17f41a3dc4da0f00bb95366be128538ce27763d81f832fe3c1d4efc07b5b08ad8dc9e65fb5e48546664e18cb2d3bb3fe1f56fa7aae718c5e3bbdeaf70e15023f6a25b72a2d177fcfd04211d40664fe",
+ "c3c4d3b31f1f5f9538923df3478c84fffaef411520a542da9a220ee4132eabb9d718b5076fb2f985485e8ba058330aed27ddfd3afa3db34aa60301088caec3d0053828c0c2bc87e2e61db5ea5a29f62fdad9c8b5fc5063ec4ee865e5b2e35fac0c7a835d5f57a1b1079833c25fc38fcb14311c54f8a3bd251bca19342d69e5785f9c2e43cf189d421c76c8e8db925d70fa0fae5ee3a28c4047c23a2b8a167ce53f35ced33bec822b88b06f41558c47d4fed1bfa3e21eb060df4d8ba1",
+ "8d55e92136992ba23856c1aea109766fc44772477efc932b3194af2265e433ed77d63b44d2a1cff2e8680eff120a430fe012f0f09c6201d546e13ad46fc4ce910eab27bb1569879abed2d9c37fae9f1267c2216ec5debcb20d4de58461a621e6ce8946899de81c0add44d35e27b7982a97f2a5e6314901caebe41dbba35f48bc9244ca6dca2bdde7306435892f287036df088633a070c2e385815ab3e2bfc1a47c05a5b9fe0e80dd6e38e4713a70c8f82bd32475eea8400c7bc67f59cf",
+ "5016284e20362610fa05ca9d789cad25f6d43263787e7e085476764ce4a8908ce99b262b375e9d106170b1bec1f473d5e777e0c1896533040e39c8c1465e07907ef5860e14e4d8310013e35f12090e0bfc687474b1f15f3dd2033a0edac5246102da4deec7e188c3517d84d9c2a0a4497a4c5f82a30f1ba009e45ee6eb3ab4368c720ea6feee428ffd2c4cc52debb8d634a64176572c72368f94a66689f23f8a01218f532117af5a8060d140e7ca435a92882fcb5630ebe14a4805f1dc83",
+ "05456ec59b8d41bbd736727976b96b38c43827f9e16169be673ff37870c2ecd5f0d1ea1a136be4cc7b047a02a4421d484fd2a12ece418e42ee391a13a0b1df5a0162b29ab70d3fe3e04ba6ab26b37d62b7cf05a5e2f033611bf970b8e1f30e198e483e740fa9618c1e8677e07b61296b94a9787a68fba622d7653b5568f4a8628025939b0f74389ea8fced6098c065bf2a869fd8e07d705eadb53006be2abb716a3114ceb0236d7e916f037cb954cf977720855d12be76d900ca124a2a66bb",
+ "eb6f60b83fcee77060ff346aaf6ec34d82a8af469947d3b5074cde8eb26566eb1fa039bcc707738df1e95869bd827c246e88436f0614d9834ead5392ef376105c4a9f370071cdeaaff6ca0f18b74c3a48d19a717253c49bd9009ccbfdd5728a08b7d112a2ed8dbafbbb46d7a75dc9a05e09bfde1a0a92d74a51887f9d123d7896e9f9d0057b660ed7d55454c069d3c5260411db4cdc67e7b74f680d7ac4b9dcc2f8baf72e15e6b3cafebcdf449a6436ed2c398b675f79c644747c57553bf7ea2",
+ "187a88e88514f6c4157c1ba40b442baae1ae563a6c989277443b12a219aa484cb9fa8adbb9a29d429f50155321b15664926317477079c7060dfdaa84c1d74bba78892c34e6f21ad35208d2ae622012401696bff5cd57b6485944b3db7b9071fa5f57fbfb1085d91bb9cff5808d662cdc6c8157249478262c44b7fbc397ed42a4977b202e817717bfccc9f0467294062313f7705251ed09573f16d23429361fada259dfb300369c4198f07341b38e84d02cdb74af5de6aab1fc2026208ea7c418c0",
+ "be31bc96606d0fab007e5caeded2f1c9f747c759777e9b6eef962bed49e45a1d4fc993e279d024915e600865ecb087b960584be18c41114d3c43f92169b9e0e1f85a0ebcd4e196376ccdc920e66103cd3b1c58407d0aafd0e003c4e341a1daddb9f4faba974362a32f35db83384b05ae8e3322d728893861afd8b1c940de5a17f691e763ce4969b6d94f67fb4a0235d100225bd8602f291388f0ca4a568748ad0d6040f1262eac2aede6cd27419bb78a394c1ffad72c262be8c3f9d9619d633e51d0",
+ "4d83d85ca838b4518588f2a90228a4dd18f14dd5b4c012d26298a97d848abbd825d221d02cceb6e8c701b4ad00e1dee4889b5c533e4bb60f1f41a4a61ee5478be2c1b1016c30345afd7a5253668260515e70751f22c8b4022d7fe4877d7bbce90b46531507dd3e89549e7fd58ea28f4cb23d33662bd003c1345ba94cc4b06867f778957901a8c441bee0f3b12e16463a51f7e50690356971dd73a686a49fda1eae46c9d54fba262811d698025d0ee053f1c58591c3bb3cbde69de0b31549ef5b69cf10",
+ "cdeb07d36dc5f9a1cd717a9e9cca37a2ce93caa298eee63571f7d6c5fde2a11c666cf53cf2dcb41ca2ea2319e7230ca68e38c647905928713a13982bf47fe33d7095ebd50b2df976208920a43eb2e29b942f32467403c45cea18bf44e0f6aeb155b48a8e5c471fec972a9d62f7ae093d2758f0aaec7ca50cb4725bfa219f1a3a46ad6bde7361f445f86b94d66b8ece080e56c510250693a5d0ea0ae87b4421860b853bcf0381eae4f1bf7c5c0472a93ad18407bc88475ab8560d344a921d3e86a02da397",
+ "a598fad52852c5d51ae3b10528fc1f722e21d44fbd42ae5acdf20e85a28532e646a223d27fd907bfd38eb8bb75175636892f8242877aab89e8c0824d368f3339ce7a82aa4e5af6db1f3b588a4d667a00f67bee37cfd2724dde06d2909fb9e58d892f4cfd2c4ca85acdf8256f5458b030a6bda151154ff2e6d7a8da90b54a2884c8a99fab5a4ac211ff23dc0975f4f592fd1b6b9dc7783bdcd2d4ca4e68d2902f2013e122cb62e2bff6b0a98ec55ba25837e21f1cfe67739b568d43e6413dab2bd1dc471e5a",
+ "17b68c74c9fe4926e8102070916a4e381b9fe25f5973c9bd4b04ce25749fc18931f37a65a356d3f5e5a1ef125d546f4f0ea797c15fb2efea6fbfcc5739c564693d47adeb12dcb3d98a2830719b13247792cb2491dca159a28138c6cff925aca42f4fdb02e73fbd508ec49b25c60703a7595a3e8f44b155b371d525e48e7e5dc84ac7b17c52bf5e526a67e7187234a2f19f57c548c70fc0b27183df73ffa53fa58b658034c896fa791ae9a7fd2620f5e46ce84c842a6e60e9324ae4db224ffc87d9617cb85ca2",
+ "b9e4267ea39e1de1fed0579f93bb351007c9f8fcdd811053fae33f09e2753d7428f04e1a9efcd45ea701a5d87a35b3afb2e6b65365dee6ead0bbb611b7797b212ac688653f542e604a39df277f12514ddfee3b4e27b98395c2cd97a203f1f1153c50327965770802ec2c9783edc428271762b275471e7ac65ac36523df28b0d7e6e6ccc7674268a132a63411fc82c0738dbb68af003b769a0bf9e6587b36476cb465350fee13f88ea355d47ffac7b0f964f4139db11b7642cb8d75fe1bc74d859b6d9e884f75ac",
+ "8ca704fe7208fe5f9c23110c0b3b4eee0ef632cae82bda68d8db2436ad409aa05cf159223586e1e6d8bdae9f316ea786809fbe7fe81ec61c61552d3a83cd6beaf652d1263862664df6aae321d0323440430f400f291c3efbe5d5c690b0cc6b0bf871b3933befb40bc870e2ee1ebb68025a2dcc11b68daadef6be29b5f21e440374301bde1e80dcfade4c9d681480e65ec494a6af48df232c3d51447b9d06be714949249c44c43cf73ed13ef0d533e770284e51369d94ae241a5fb2f163893071b2b4c118aeaf9eae",
+ "4fd8dd01012bb4df82bf42e0683f998e6f52dd9c5617bae33f867d6c0b69798cead8179346d70acc941abbbdd26e3229d5651361d2252c72ff22db2938d06ff6fc29a42fdf800ae967d06479bc7bbb8e71f40b1190a4b7189ffc9a7096cdb76d40aec424e1388e1eb7ef4ac3b34f3f089da8fda7d1927f5d775c0b2801d22dd1265c973158f640cec93edfed06dc80b20ef8c496b98289d54d46ccd205951cbb0f4e7daeb866b60bacb483411e4382b6f04d472843186bd0e31fbaa93e5c901ec028efafeb45fc551a",
+ "e9ee1b22b04b321a5fdd8301627011f583887d77560fb0f35552e207561f81e38ac58a0d0aeaf832d1ee72d913720d01f75574e9a321864fe95f4d0d8f0b8db97649a53e71e940aede5c40b4b9105daa42a6fb2811b61209247534cbaf830b07abe338d75d2f5f4eb1c3cf151e9edabe2c8d5f6fff08fac1495ef48160b100d30dcb0676700bcceb28723a29980ab0766a93abb8cb3d1963007db8458ed99b689d2a7c28c788743c80e8c1239b20982c81dadd0eed6740c65fbc4ef15c7b5569cb9fc997c6550a34b3b2",
+ "ec01e3a60964360f7f23ab0b22e021815765ad706f242265ebc19a2bb9e4eac94393952dcf61aae47682671a10f9165f0b20adf83a6706bfbdcf04c6faba6114653a35584267267873291c6fe7ff5f7695243143421509502c8875aafa9e9afe5be5ef2c851c7f35d69be5d3896000ccdbbfab5c238bb34d607cfe2d55d748880545b4aa7ca61137992925189025c62654b1f20d49c3ccd75aa73ce99cd7258dabedd6480a9f5185531fc0118beb68cc0a9cd182f6973287cf9252e12be5b619f15c25b65c71b7a316ebfd",
+ "db51a2f84704b78414093aa93708ec5e78573595c6e3a16c9e15744fa0f98ec78a1b3ed1e16f9717c01f6cab1bff0d56367ffc516c2e33261074935e0735ccf0d018744b4d28450f9a4db0dcf7ff504d3183aa967f76a507357948da9018fc38f150db53e2df6cea14466f03792f8bc11bdb5266dd6d508cde9e12ff04305c0295de29de19d491ad86e766774bb517e7e65befb1c5e2c267f013e235d8483e177214f89978b4cdc81aa7eff8b39f2825ad3a1b6ac1424e30edd49b067d770f16e74dd7a9c3af2ad74289a676",
+ "00e40f30ae3746edad0f5dd03d0e640933cf3d1694804c1e1ed6399ac36611d405196ee48f129344a8512feda16a354517871322bd5d9c6a1b592933eab531923efb393ffb23d9109cbe1075cebfa5fb917b40df028a621460ff6783c798792cb1d9635b5a6f84ec13918fa302924649b5c7fcb1f7007f0d2f06e9cfd7c27491e565a96c68a0c3644f92cd8f38857258c33801c5d537a83dfe583cba59d7eec7e394199c0a2660a62fabe3ed2099d57f315a6cd8de1a4ade29d977f15d65759cff433e5ac0c182aef3761163e1",
+ "3c5ea24d0d9b618294a263f062b2414a722be4eb10dfc346a6ec3b821d7396eba61cd6ef33618b04cd087a811f299d4606820227f16000d7c839062b96d3e3f59cd1a082448d13fc8f56b3fa7fb5f66d0350aa3b72dd7c165d590282f7da2e12cfe9e60e1796122bb8c2d40fdc2997af634b9c6b127a893dfb3467909378300db3da911be1d7b616bb8e0572433e65527e15d936500a2c60e9f9909dcf22ab5e4b6700f0238c205b4a813626fac3d945bab2637fb08203044a73d20c9a3fcf7c3fc4eb7807c3276dd5f73ce89597",
+ "9271aeeebfac46f4de85df78f1bfd36136aa8905e15835c9e1941176f71e3aa5b1b131843d40479735e23e182a2bd71f66f6149dccb7ed8c16469079dc8590bbf165374951785f4531f7e7361de62f936cfb23a2b5bdf186632e7042a0dd451fdc9b7208f923f3a5f250ae590ec348c63a16c3aacaf7379f53b5dd4152dcd40d23e683e2156e64c592ffc07e2cd6bbeebef4dd590b2f6b2bcbf08fcd111c079f5c4033adb6c17574f8756ecd87be27eff1d7c8e8d0324438d59ae171d5a17128fbcb5533d921bd044a2038a5046b33",
+ "4e3e533d5bcb15793d1b9d0468aaee801f32fdb486b11027183553a09ddbee8213924296f2815dc61577297459e834bf1c7a53f87d43782209e589b8295219ba7073a8fff18ad647fdb474fa39e1faa69911bf83438d5f64fe52f38ce6a991f25812c8f548de7bf2fdea7e9b4782beb4011d3567184c817521a2ba0ebad75b892f7f8e35d68b099827a1b08a84ec5e8125651d6f260295684d0ab1011a9209d2bdeb75128bf5364774d7df91e0746b7b08bda9185035f4f226e7d0a1946fcaa9c607a66b185d8546aac2800e85b74e67",
+ "b5d89fa2d94531093365d1259cc6fe8827fea48e6374c8b9a8c4d2209c280fa5c44958a1847222a692a59e6aa2696e6cdc8a543dd89b0ce03bc293b4e78d6ef48e1839694ccd5c65661143095c705b07e3ced84a0f5959114dd89deb956ab3fac8130eb4a878278205b801ae41a29e34146192308c4e759b374757b0c3b00319bce92a1b95a4d2ee179fd6714ff96155d26f693a5bc973f84ac8b3b91e3926276297532d98b46992a3f104c08100bf1671c43134bac280c617da711e90a0100137525375ebb12802a428885ae7fce6514a",
+ "40e3d8048fc10650cb8a7fc2e7113e26dec34f9ca2d5129cd10a8e8e44d113d61ee48c7d003e19fd307fc6debd70feb30243f298c510ccc4418355ce143066f067ad7c6de7288c3080e7ad46a23c8d34deb55a43e652fe90444ad3c57d3ec1e1c489d63ef915a24bc74a7925a0a7b1e1523f21ca8fee78df24e3d0a68d0013423db97c280799a0618229c0f2c167289a891e5c8d6661ab21285951c31710e3b5fe55f6347fe16d9b40507948a59252efeb616df83e5c098b07d0a7247cd371daff0e50491c582503fd89f79ba94d6af9ed76",
+ "1fa444de01dd3901e2b4684e3d7a799ffa02d85afd35fb30fe4c9d672837bee6dd8a3b8608b4bb5e589220ad5a854f46b46e41c6d57ad124a46beab4169ff69fee7e3838a6165e19dad8eb5d7bf53d4edd3cd2769daf219510a02fdd2afe0c0e1da3cd30fcd1aa88b68965586f07a25a1720fbd90a096ea30fc8e945e3637d7857c8a9c0ab4154ffb2000e57b5f9adfa4e4eaf8065bc3c2b2e75f495963325588785a6ce417dcddffd299873b15dcccca128d63cd4eeeadb64cda28099a9ad7c80d34844901f26b88b00b9aafeb2f90286d29d",
+ "fde0a0d9d813983bd1f55cf778a003a2023b34a555322ab280584537bc6bdd844d22a7d6066c18da83ec09f3d8d5a1aab4be0d5ce19b436052f6e259a4b49017a1f47f1fe2bf115d5bc8599fb216351c60dd6b1bedb2e6f4dcadf424b833501b6f099cbfad9e2290680fb69c25032b42a6274f7cb9b5c5950401354838a45f7cb77b95bf54718e2f3d3d9fb91eb2311903980277396398d9736d8e92fd838594ac8a537c6c529db5a8a4f89290e6ba6f20ac0e5ed6fef40901d0e0e8e3e502990811f9acaae555dd54eb1bcd96b513e2fe751bec",
+ "9f8e0caec87858599f5ab29bff86da78a841a918a023a111098687ecdf2747612d3f3809d9ca400b878bd4f92c43a1004f1c17c7f19a3cd1ce449bd2b23aff551623c37dd8c0be56bf3fd857b500c2b9f9ccea62481944090a3cf3b6ee81d9af8eeb60f65ef150f9fa4d3ed6ce4762d3d4f174ee8ccd460c25cafac0ea5ec8a6a4b2f9e8c0520cb7061155e532cb65f188b01e4b9086db951f504b060c296b326b3fc1c590498ecce594f828f4a10ea416675720ae505295d38a791bd0e93f428448a8f4c1fc0af53604a9e8255384d29ae5c334e2",
+ "33d1e683a4c97ee6bbaa5f9df1a88cb53b7f3c157b6045d70a56fda0ccbd3a1fa1f049cd564da072b53f415bf5fb843771c1d2551fd075d33377362b2f7c0645f9723123d11975991db8a2b518f02e2c7c30342a044754290bae2c77496d755e5981f12e6b0a0174280b958bf11ed628a9062775993ced04bf752ea8d165e3ac2177d7cd1b9371c44efa98f0b3e68602a839d384eec007979f46429dafb138cbc231ad928a9f65f7d66fac77416395e8f1debaaf76ec2e4e03e8674102cd26f614739f3ec9f949033df1fb97e87c2326d65aef94ed5f",
+ "180048f09d0b480887af7fd548a85abf605440c1ddde6afe4c30c30670233f7bf928f43b4681f59279ebbda5e8f8f2a1abefdee129e18ac60f9224e90b38b0aabd01308e0a27f41b6fb2ee07ee176ec9048c5fe33c3f7c791469c81f30e28170585b9f3e7e3c8c2e9d74370cb4518f13bf2dee048cbd98ffa32d85e43bcc64a626b40efb51ce712925fdd6fee006dc68b88004a81549d2121986dd1966084cd654a7c6686b3bae32afbd9625e09344e85cf9611ea08dfce835a2e5b3726e69ae8a76a97db60fcc539944ba4b1e8449e4d9802ae99fae86",
+ "13c0bc2f5eb887cd90eae426143764cf82b3545998c386007cca871890912217aa143ac4ed4ddb5a7495b704aa4de18419b8664b15bc26cfc6596a4d2ae408f98b47a566476d5802d594ba84c2f538def9d016661f6404bb2337a3932a24f6e30073a6c9c274b940c62c727242e24466084a3ea336365d71ea8fa6499c0ea8d59eea505f1126b99c795023c4963aa0d99323d0391e8701110edf551b2d3799e1063ca443f1add162156e445502ca1a052fe70c289838593b58839fc63de128a03e2bbf389e22ae0cf957fd03315ee407b096cc1cfd92dee6",
+ "6f1eb607d679efef065df08987a1174aab41bdac8aece7726dfa65805d6fff5b3d17a672d96b770dc32165f144f0f7324822a5c87563b7cd9e37a742ae83ef245d09006d91576f435a03476f509ea2936636232f66aa7f6cdf1ac187bbd1fcb8e20f8791866e60ed96c73374c12ac16795e999b891c64507d2dbd97e5fc29fac750ad27f2937cbcd29fdafccf27ab22453834d475f6186eaf975a36fad5c8bd61c21da554e1ded46c4c39765dcf5c8f5ccfb49b6a4dc562c919d0c7d8940ec536ab2448ec3c9a9c8b0e8fd4870cad9de2577c7b0c38563f355",
+ "dcdd993c94d3acbc555f464871a32c5da6f13b3d5bbc3e34429705e8ad2e76393fdd96a69a94acb652f5dc3c120d41187e9aa919669f727c4868013b0cb6acc165c1b7706c52248e15c3bf81eb6c147619467945c7c48fa14a73e7c3d5bec91706c567145342a026c9d97eff97ec672c5debb9df1a998083b0b0081d65c517b3e5634c95e347e781aa30ca1c8af815e2e494d844e847fdcb41622894a518dc36571123a40bfdbe8c4f4cff44d83c61dd9dcd24c464c53b395edb31efee9f3aa080e87cdc3d22d613ae84a53c9249c32c96f9a3bc4629bb126a70",
+ "49971f9823e63c3a72574d977953329e813b22a8387cd13f56d8ea77a5d1a8a20012632d1d8732bbcb9f756b9675aab5db927beacab7ca263e5718b8dfa7b2eed9a91bf5ed163b16139d45f7b8cc7e3f7bdda6202106f67dfb23b7c315ee3e17a09d466b1e6b13e7c7428184a979f5358667b4fa8bd40bcc8ea46058db44587a85377ac46bf155136c09ac58cb6c27f28e17028c91e7e8f74d5b500e56293b316974f02b9d9ea205d9b6ac4cfb74eb8eb0c944577fd2f41316368307beab3e327bf7dbaa0a4428836ec4e895dea635234abeaf113ceeadac33c7a3",
+ "c57a9cc958cee983599b04fe694f15fb470fcbc53e4bfcc00a27351b12d5d2434444253ad4184e87b81b738922ffd7ff1dc1e54f39c5518b49fb8fe50d63e3935f99e4bd125e8dc0ba8a17fd62de709339a43fabe15cf86d96a54010112170c340cfac4132182eed7301402bc7c8276089dec38488af145cb6222525894658f03501204b7a66aba0be1b557b28a2f652d66f7313ed825ecc4d8596c1be7420d4425b86a1a90a5b7f30d0f24e0d1aae0eb619ca457a71699e44be612a4011c597ee80b94d5507e429d7fc6af22579cd6ad642723b05ef169fade526fb",
+ "0568a672cd1ecbaa947045b712e2ac27995392fbef8f9488f79803cbee561c212287f080eca95adb5ba42739d78e3ba667f06045d87850d3a0499358649caa257ad29f1a9c511e7054db20554d15cbb55ff854afa45cae475c729cea72ede953522031865bc02b95589ed4d9841c552a8cc94904a93ed09ed77222f6c178195056be59bc4e96a815adf534e6b466fb47e262ff79c803c157a21b6e2269c2e0abeb494113cd868d8466e82d4b2f6a28b73645853d96bc9242515d803e33294848d3fe42fdff68da53c03491636beede47ff1399dd3d54a5e914d55d7adf",
+ "3f19f61a4cd085796731ac9f85a75a8bce77031932c31762d87d8b8d07b8bd19ff78d6b7d1bd1e87f3a4f41aad03b6c4d17a6cbc86be55f7c8b88ada047bb04f8d49f1c34bcf81cc0f3389ad01a758fc7eeb0072aa9ad1481992bfdde82e438e75590a4423832dfbe3756e2229ea873bc3606e6d72174cb2163bf40b5d49c81009dab85ecc03e311351bbf96e32c030a2b276a7698cb25bc2c967acb3213161a1fdde7d912cd6a804490f8056c47da1333f6e35c41e749c2c23919cb9af5eec5652e6e072b034fb1682e9aaa194a9c0bd456ea0b008d14dbce37967a7a8e",
+ "705f98f632d99d3651793825c38dc4deda56c59eac539da6a0159c83131cf8ab6f2ee0c3b74111fde351f7aa1a8c500a0cecab17c212d2c58ca09eae608c8eefc922b9902ef8d6832f799ba48c3c28aa702b3242107edeba01daafe424406a3822965056cfe8783455a671e93b1e2eae2321364f1871471c82124df33bc09e1b52882bd7e1c4c7d0b2f3dd4a28c2a002a43246768af0700f9659de99d62167be93177aabf19d678e79e9c726ac510d94e74873eda99620a3961930cd91937c88a06d8153d64fd60da7ca38cf26d1d4f04a0df273f52127c53fdc593f0f8df9",
+ "ea6f8e977c954657b45f25480ff42c36c7a10c77caa26eb1c907062e24fbca5aebc65cacca0de10abea8c78322f08672e13d8ac16996eca1aa17402eaea4c1cc6c800b22dc18cb8d620192d74bac02c07b5cfa61e513c7f28b7e29b9700e0e442720bf4c669d4995da19d19f841d9eb68cc74153592591e3bf059ef616b95305aa453b32fe99a91afb35bd482cf2b7aa42702837a53be3c38883d2963020e347556f841254ec6b85854485fe8c520b05f2ea67a9bf3981555c20991e2bacd4db5b418228b6002d8d41c025cb472bf5443aaa885974a408ea7f2e3f932c600deb",
+ "408190134ed06556811b1af808ab2d986aff152a28de2c41a2207c0ccc18125ac20f48384de89ea7c80cda1da14e60cc1599943646b4c0082bbcda2d9fa55a13e9df2934edf15eb4fd41f25fa3dd706ab6de522ed351b106321e494e7a27d5f7caf44ec6fadf1122d227eefc0f57aefc140d2c63d07dcbfd65790b1099745ed042cfd1548242076b98e616b76ff0d53db5179df8dd62c06a36a8b9e95a671e2a9b9dd3fb187a31ae5828d218ec5851913e0b52e2532bd4bf9e7b349f32de2b6d5d3cdf9f372d49617b6220c93c05962327e99a0480488443349f0fd54c1860f7c8",
+ "5f9e5c6f38573a85010a9d84d33f29c057003b2645e3ea6f72cbc7af95d197ce6a06b13fea81722853e6991791b8b15091cd066f5ed913592ed3d3af5370d39ba22beeb2a582a414b16824b77e194a094c2afdcc09aa73ce36f4943cca5ae32c5017dc398801dd92a47382d9327c9f6cffd38ca4167cd836f7855fc5ff048d8efba378cdde224905a0425e6b1de061fc951c5e624a5153b008ad41160a710b3ff2081748d5e02deb9f841f4fc6cf4a15153dd4fe874fd447482696283e79ee0e6bc8c1c0409baa5ab02c5209c319e3169b2476149c0c6e541c6197ca46e004eef533",
+ "218c6b3508aec69574f2b5039b30b942b72a8349d05f48ff945bbbe5c8957d5a6199492a6bf54bab821c9377e2edfa4c908384664d2c80112d5e805d66e0a551b941021be17dd20bd825bea9a3b6afb1b8c605805b3bda58750f03ea5c953a698494b425d8980c69f34d1c3f6b5866e8717031152a127215c256e08873c21b0f5cc85875d0f7c94601659150c04cd5fe5d381ba29983a2d94fcd3a65a94c53c7279cd000dddd4253d8cff8d7f6ace10247fe3bc30d63ba4bb54f557b3d22a3924369430d71ab37b701e9500bda70b5a643704858beed4726a889b6c9c91584194c68f1",
+ "dac26aa7273fc25d6e044c79fc2bfa46e59892a42bbca59a86826c91e76ab03e4bd9f7c0b5f08d1931d88b36ea77d94f7ba67cd4f1d3086e529427201119096ae066ae6f170940830ed7900de7bb9d66e09788287403a4ecc93c6da975d2fb08e918840a236c15f5d3a8f7375c2eeebbf6f01a6e7f29ca2b8d42df158414c320777433663c59fdcd1f39ca68e3473db721be7ce8c6dba5fddc024f94fedb286b0477581d451313ca8c737484daf60d67f9b2d56d4bcc271f7e9ae958c7f258efbc74d25753e0516f28282461941bf2dcc7dd8c7df6173b89760cefcac07190243ff863fb",
+ "c46e6512e6797cc7a54254a1b26b2de29aa83d6c4b1ea5a2786fbcec388270625b12635eae39e1fba013f8a65219421bca8b52a8ddfd431cda60299bdf160734d5a7450ec79620058522702174ae451b9bfa7c4a455fbbee3e1d048c7d4bac5131018228f137c8e130440c7059b4f15eaa34ce872a851a16ce86f982df78a00be4d564da2003a450ddee9ab43ea876b8b4b65c84f0b39265fd5456417afb5bc54997c986e66fc222f2123ba5e719c4d6b9a177b188277df384f1125821cf19d5248cef0be183ccdc84ac194506f740ed2188b2689ea4c9236a9e9e3a2fff85b6af4e9b49a3",
+ "1ccd4d278d67b65cf2564ecd4de1b55fe07adc80e1f735fe2f08ea53fd3977323689122c29c798957abaff6aba09bdcbf661d77f4dc8913ab1fe2bef38846166e3834785e7105d746484eff8c656af5d8c7854abc1c62b7fadb65521dc6f793d978bda9838eb3800417d32e8a24d8c8cb1d18a5de6ca79d9e1b0ff9aa25e6218fe944cf18666fecc1e31334b390260dbe0997539e1b02f6366b2aea4f4a21efe04f4b97568fcb39e59919d5ebac6543d5d0f48fc66b923c34aac377dc95c20329b837b6ed5e8d9a3d2089cd0d8f025658006ff41cbdaccca618822ca590ab155253f8bc1c7f5",
+ "9875209588395ee3c9fdd793fd48717cc84c8c3ea622b2ccc4a1be4448e6034b7810569855255031f10be5ffd714b05f9ce01972d712d40abf03d4d0ce175813a7a668f761324996093fc2aa5912f7fc2abdadd8775d2b4d9ad492216293381460ed8f6db3d641d1525f4242c348bbfe504c704f215dc461de51b5c75c1aae967936963848f16c673eca5e78dfd47eb19001d52d1bcf96c98956dad5ddf594a5da757e7ca35f2f69803b784e66ac5a58b75c228b8266ec592505e5d1ca87d81225738855f15bc0914677e81593fd409e77d159f8a908f67788de9eb06c5561547aada96c47c535",
+ "40c90e375e366f3756d89091eb3eed9fe0fbfc5638700af4617d358812bac53124a2205dd6756456787d49cd6a35e302479a0992288f47532e4ea7ab62fc5ad5adc690a5d9a446f7e035ad4641bd8dae83946aee3338ec984ccb5cc633e1409f2531eeffe05532a8b0062ba99454c9aeabf8ecb94db195af7032bfebc22912f49d39330add47ff8fa5720612d697f0b602738930e060a1bb214efc5e292224cf34e29deaea6b1b1ff847e94ecc997325ac38df61db45d82bf0e74a664d2fe085c20b04c39e90d6a170b68d2f1d373f00c731c524456ada73d659aaac9df3191a7a3865083343fc13",
+ "e8800d82e072210ca6d7fa2472028974780b76aad4bcb9ad362422dd05ae3232668251d164daa375a43b26a38cce28dbeb3dee1a4a579f70d0fe7febb29b5ece8aa836e050fb3d188c63aa9c3c0da6c717d86458a6096b5effceb964efdec7035960c09ccd10dea3c5f1c7f9f478d5887ebbe2e15c5ff85dbacbc444bb951c4eec7abecb89ed80187e409e2972ffe1a5f01562af109f2cf09471cf72cf83a3bb8f4e2ef38ed0e326b698296394e5b2718a5000c01425708e8ad0461e62462d8819c2377f13ab1be2c7c9f33dc06fe23cad27b87569f2ce2e56e4b2c60c7b1b3d370841d89ebdc1f192",
+ "796d6d1447d5b7e8c55cd8b2f8b7010db39f27565f907e3fc0e464ea2d4bb52b37f10e7c6dcfc59231b9cdee12c32aeb4adbc42b86e86eb6defb5b69e6ca75e1f4d0dae3e124e5a1b8b6697f7e10b0403f1f0a5ff848eef3752837a9ba17780f16a9a709188a8d5b89a2fa74adb2e651163b1c2b3d261e225c9158dcd9eb7ac3d6704cee290cdff6bcb3cb90cee030aa0d19d4693655c3c30ac6fc06d2ae37787c47126d57ed9a6bef5f8a6c56859aefc08755739a95aac57a4dd916a92ba9f3afbf969df8085949615033365c751a9a3e1a18cee98a69d22e64009bebf8307169b6c61de0617ecfafdf",
+ "4f9057183566153cf337b07c3f5556006de54c56b2a1e5326c07aaeabd1886ec6f1641358925db232b2f0dbf75229c796a7395b2f934c1f99090bec1123f3c841b1cb3c5b1ec42ed5408f2940f0c48a9470b852c46d6557853d459cecd2c32bbcd8ee21fa11e385eef0857cba4d8545a61b52a484cdd779db4739fbc7aa9860dcabe0488b98fa0b60c3f7d6153db279000a52ffb573dab37d2ab1896a90e5deb7ac6bbe56239085c325d83a917dc6e8a448425b718c2356b9f3066163555ec444f372e184e02c8c4c69b1c1c2ae2b51e45b98f73d933d18750968945ca85d6bbb22014b4c4015262e3c40d",
+ "79dcca7d8b81a61359e4aece21f3df7b99518ce70bd2f57a18bab5e7114af2add0a0cea7f319d69f231f060e0a539d9a23fb3e95451ce8c6340cfb09edf931df84203a39226dd9eb278f11b691ef612585b973daab373e65d11325898badf6732100371fd759960fa8fec373268421d28bffdb9b12a430b92fe4b07566ca0c89e616e49f8fc75ccd9cdc66db820d7c02e109aa5ed86b89770262918a518f90a2292f6b68d68ae03992e4259a17a23c84ec2a417f082b5abf3a26e44d2278ecb8ba9456965303a75f25394d1aaf5544590e74b14d8a4cc4050be2b0ebcfe4d2db6b12a02c68a3bcdda70301f3",
+ "848755dc31e25e9a42f9ec12d847d19f292c14c162c9aba49e972cb123b58b8e57bb263a923929833373858594ff52dbc298dbbc078599194e4c07b0e5fc1e10808bbacdb6e93c72b333685cf961f28eb0d5a395c63266b01f130d25db384b356e5da6d01042fc2359581b89c63b3bb2d1ce897fbc9e83fe85d9666cb60e6a8c657f70caad5387b8a045bf91095606802c8424ea8ac52ef29386dc46183378a5fcb2cb927428b8c070f1c42aafd3bc70ca25437807696a46873cfeb7b80ba2ebc3c4272443d445e46343a1465253a9eebd532a0d1d2c18264b91ff45159f245404ae9335f2af55c802772426b4",
+ "ecaa6e999ef355a0768730edb835db411829a3764f79d764bb5682af6d00f51b313e017b83fffe2e332cd4a3de0a81d6a52084d5748346a1f81eb9b183ff6d93d05edc00e938d001c90872dfe234e8dd085f639af168af4a07e18f1c56ca6c7c1addffc4a70eb4660666dda0321636c3f83479ad3b64e23d749620413a2ecdcc52ad4e6e63f2b817ce99c15b5d2da3792721d7158297cce65e0c04fe810d7e2434b969e4c7892b3840623e153576356e9a696fd9e7a801c25de621a7849da3f99158d3d09bf039f43c510c8ffb00fa3e9a3c12d2c8062dd25b8dabe53d8581e30427e81c3dfc2d455352487e1255",
+ "23a3fe80e3636313fdf922a1359514d9f31775e1adf24285e8001c04dbce866df055edf25b506e18953492a173ba5aa0c1ec758123406a97025ba9b6b7a97eb14734424d1a7841ec0eaeba0051d6e9734263bea1af9895a3b8c83d8c854da2ae7832bdd7c285b73f8113c3821cced38b3656b4e6369a9f8327cd368f04128f1d78b6b4260f55995277feffa15e34532cd0306c1f47354667c17018ee012a791af2dbbc7afc92c388008c601740cccbbe66f1eb06ea657e9d478066c2bd2093ab62cd94abadc002722f50968e8acf361658fc64f50685a5b1b004888b3b4f64a4ddb67bec7e4ac64c9ee8deeda896b9",
+ "758f3567cd992228386a1c01930f7c52a9dcce28fdc1aaa54b0fed97d9a54f1df805f31bac12d559e90a2063cd7df8311a148f6904f78c5440f75e49877c0c0855d59c7f7ee52837e6ef3e54a568a7b38a0d5b896e298c8e46a56d24d8cabda8aeff85a622a3e7c87483ba921f34156defd185f608e2241224286e38121a162c2ba7604f68484717196f6628861a948180e8f06c6cc1ec66d032cf8d16da039cd74277cde31e535bc1692a44046e16881c954af3cd91dc49b443a3680e4bc42a954a46ebd1368b1398edd7580f935514b15c7fbfa9b40048a35122283af731f5e460aa85b66e65f49a9d158699bd2870",
+ "fe511e86971cea2b6af91b2afa898d9b067fa71780790bb409189f5debe719f405e16acf7c4306a6e6ac5cd535290efe088943b9e6c5d25bfc508023c1b105d20d57252fee8cdbddb4d34a6ec2f72e8d55be55afcafd2e922ab8c31888bec4e816d04f0b2cd23df6e04720969c5152b3563c6da37e4608554cc7b8715bc10aba6a2e3b6fbcd35408df0dd73a9076bfad32b741fcdb0edfb563b3f753508b9b26f0a91673255f9bcda2b9a120f6bfa0632b6551ca517d846a747b66ebda1b2170891ece94c19ce8bf682cc94afdf0053fba4e4f0530935c07cdd6f879c999a8c4328ef6d3e0a37974a230ada83910604337",
+ "a6024f5b959698c0de45f4f29e1803f99dc8112989c536e5a1337e281bc856ff721e986de183d7b0ea9eb61166830ae5d6d6bc857dc833ff189b52889b8e2bd3f35b4937624d9b36dc5f19db44f0772508029784c7dac9568d28609058bc437e2f79f95b12307d8a8fb042d7fd6ee910a9e8df609ede3283f958ba918a9925a0b1d0f9f9f232062315f28a52cbd60e71c09d83e0f6600f508f0ae8ad7642c080ffc618fcd2314e26f67f1529342569f6df37017f7e3b2dac32ad88d56d175ab22205ee7e3ee94720d76933a21132e110fefbb0689a3adbaa4c685f43652136d09b3a359b5c671e38f11915cb5612db2ae294",
+ "af6de0e227bd78494acb559ddf34d8a7d55a03912384831be21c38376f39cda8a864aff7a48aed758f6bdf777779a669068a75ce82a06f6b3325c855ed83daf5513a078a61f7dc6c1622a633367e5f3a33e765c8ec5d8d54f48494006fdbf8922063e5340013e312871b7f8f8e5ea439c0d4cb78e2f19dd11f010729b692c65dd0d347f0ce53de9d849224666ea2f6487f1c6f953e8f9dbfd3d6de291c3e9d045e633cfd83c89d2f2327d0b2f31f72ac1604a3db1febc5f22cad08153278047210cc2894582c251a014c652e3951593e70e52a5d7451be8924b64f85c8247dab6268d24710b39fc1c07b4ac829fbda34ed79b5",
+ "d7314e8b1ff82100b8f5870da62b61c31ab37ace9e6a7b6f7d294571523783c1fdedcbc00dd487dd6f848c34aab493507d07071b5eb59d1a2346068c7f356755fbde3d2cab67514f8c3a12d6ff9f96a977a9ac9263491bd33122a904da5386b943d35a6ba383932df07f259b6b45f69e9b27b4ca124fb3ae143d709853eed86690bc2754d5f8865c355a44b5279d8eb31cdc00f7407fb5f5b34edc57fc7ace943565da2222dc80632ccf42f2f125ceb19714ea964c2e50603c9f8960c3f27c2ed0e18a559931c4352bd7422109a28c5e145003f55c9b7c664fdc985168868950396eaf6fefc7b73d815c1aca721d7c67da632925",
+ "2928b55c0e4d0f5cb4b60af59e9a702e3d616a8cf427c8bb03981fb8c29026d8f7d89161f36c11654f9a5e8ccb703595a58d671ecdc22c6a784abe363158682be4643002a7da5c9d268a30ea9a8d4cc24f562ab59f55c2b43af7dbcecc7e5ebe7494e82d74145a1e7d442125eb0431c5ea0939b27afa47f8ca97849f341f707660c7fbe49b7a0712fbcb6f7562ae2961425f27c7779c7534ecdeb8047ff3cb89a25159f3e1cefe42f9ef16426241f2c4d62c11d7ac43c4500dfcd184436bb4ef33260366f875230f26d81613c334dbda4736ba9d1d2966502914ec01bbe72d885606ec11da7a2cb01b29d35eebedbb0ecc73ed6c35",
+ "fd993f50e8a68c7b2c7f87511ce65b93c0aa94dcbdf2c9cca93816f0f3b2ab34c62c586fc507b4900a34cf9d0517e0fe10a89d154c5419c1f5e38de00e8834fe3dc1032abdeb10729a81655a69a12856a78ca6e12110580de879b086fd6608726541cfa9616326bdd36064bc0d1e5f9c93b41278bff6a13b2494b81e238c0c45aea1b07d855e8f3fe1478e373bd9d3957cf8a5e5b9003386793d994c7c575cff2322e2428cbbaa4f47560316ae3354a7478842ff7cc5dcbacb6e871e72b36f06d63a9aaeb9044cfb7974afdc238a5816f537dcf33ee40b4e1a5eb3cff2402b46d548264e133008d284f11b7e4e450bc3c5ff9f79b9c4",
+ "8df21892f5fc303b0de4adef1970186db6fe71bb3ea3094922e13afcfabf1d0be009f36d6f6310c5f9fda51f1a946507a055b645c296370440e5e83d8e906a2fb51f2b42de8856a81a4f28a73a8825c68ea08e5e366730bce8047011cb7d6d9be8c6f4211308fad21856284d5bc47d199988e0abf5badf8693ceeed0a2d98e8ae94b7775a42925edb1f697ffbd8e806af23145054a85e071819cca4cd48875290ca65e5ee72a9a54ff9f19c10ef4adaf8d04c9a9afcc73853fc128bbebc61f78702787c966ca6e1b1a0e4dab646acdfcd3c6bf3e5cfbec5ebe3e06c8abaa1de56e48421d87c46b5c78030afcafd91f27e7d7c85eb4872b",
+ "48ec6ec520f8e593d7b3f653eb15553de246723b81a6d0c3221aaa42a37420fba98a23796338dff5f845dce6d5a449be5ecc1887356619270461087e08d05fb60433a83d7bd00c002b09ea210b428965124b9b27d9105a71c826c1a2491cfd60e4cfa86c2da0c7100a8dc1c3f2f94b280d54e01e043acf0e966200d9fa8a41daf3b9382820786c75cadbb8841a1b2be5b6cbeb64878e4a231ae063a99b4e2308960ef0c8e2a16bb3545cc43bdf171493fb89a84f47e7973dc60cf75aeeca71e0a7ebe17d161d4fb9fe009941cc438f16a5bae6c99fcad08cac486eb2a48060b023d8730bf1d82fe60a2f036e6f52a5bff95f43bbe088933f",
+ "f4d84ed3e564c102600a795eaa9b1eaf4ad12f1a4deca1d042a0a2750ddf6201db03073d8bf553cb9dde48a1b0083827a609f7242b86584cc180964ae794b12ce55661e00e36a6ba4dbc389e6a5a85f1b45df9af7ead1b0a54db56e68639b9d438a91504e82c35d40c7bc7e048a53ac0b04accd0dadf4ac9884b0ca0e3cb5ba4336e3581be4c4760a553823ffa283a1120d4e145af56a59f2533903650f0b9e9ad9fe2e8a3c3c3dd03a1fcb709032c8835324839c735b0c051d0cbd8b5d867617c11023432e4bd275d3d0eb98a0b6cf58071a5b712922f2bc751ac7c2588c447444cde2f37a8ea5ec126425bf517e0d17c9e2999f52fee14b3",
+ "2ccea21bac9c2b70d3923309cbf2d7cb7abd1fcc8b8b002688870a80029c62397350c3c898194e5deea360bb963d26d485cb7963f8167586976ec0556950b2e86135f4a2800991ce8473bfd44a3c5e937a48b5e355ba5141bccf2131a83988d9d2a9e8e7635a956105b3512c05ef708139ced51d7a4e204c12d8a49a21e8dc6de2629a2fd092326885d9f218745fe09f6d91fb6afce250a30a63689534b6be1f26899ffa3767d835cf586aa47776700f94241bc999b1e3deefe188f37ff734f5f16ee6a00914323dc7b8a143c9137cdcc5cd08ae9566f04bb2941532674c97dff6ffa5ce3405ef8e5d27ec403114253dd6394c0167d72a0044c5",
+ "2b681c6398aee63bf862770341648bbcd31d7de7903c5903fe3d9469311320bb24d914f2af0cdca199c97214c7c679dc32a2800ba484a03c010ea6be3bb9f2c87e30a98b606050b8a3f297f12b8f92caaeceb3e844652115934874e0a1ab093a73d759b53f6a6c3096940dd22c2bb96ce6820a7b9c6d71a208de9892aa6a7209b0fff56a0cafea52b952cdd6f5752cff3309d448800b4e4c878aa595595b56b12b83fcd6ca89520c7da664e449d7b4438fc455888aad5de0fad9a06eed14afd3513b5ebbffe01775549b701181bd26370764f56eba52fdb24286ad1ac0f5418a7c429f7dfc7f3168437fa8eed7a2ed7c723a485e4c3ed14dea2e07",
+ "aadfd505a89f4aade2c3018258a7e039401b1fc6a7f3d87910dddbb880d372ec8a13c70d92245de5b8e5f9a285c33b99dc82fa2b22decee72b93a72211656ad7a52696c8e570f78be28c0e427a371dafde856e8d5ed24f83b0660b51e7fac05d93a8666dfde6def59af863f80f3e5f6801182c87422203df390dcb736b8f830052a8832eeeb0b4e27e732aaf793d166b5a3ec7745aeef3766937c2b75a276bddd145f6010c29d035e343e267cb2d828436876ec3a7ebe3b6347d4172f7a99d6821ce152e039e53deb33340b324c7f068ffb94b3cde35a8eaa12d15c3806a7ad0acec3e8c7078c1d32a28fd3eec9f32cb86e4c22166ff69e83785e851",
+ "1605b8cce529a9d6262fd4390d9e4ae5e14e0adc0ec89b028ef68dd0f373ea259aaa96f2967091dd0874c0105385e9e6da9ca68297c31afa44ef834535fb302ce5b4e49edacbbdf359fe1228a8172495b3e57014c27edd58b685110980056c50c398a64f4923f2d720b4df16d75cb36b4233660694182099c35028a972519c24764fc94e18e582b24deb3491535fc06b83837c7958522800e822201d694af0bd0aa3834e17d4b1ba36f470905ae5f8bbeeb6c4c8604d8af02baa347b07086d6989867ddd5e8e8ed7740c3469bfa2810519c55c6add1332c4c54ee9097961d6741cb12a09713a0d07645f784f42f5ad94b48b836b34263130b0483f15e3",
+ "ff9c6125b2f60bfd6c2427b279df070e430075096647599bdc68c531152c58e13858b82385d78c856092d6c74106e87ccf51ac7e673936332d9b223444eaa0e762ee258d8a733d3a515ec68ed73285e5ca183ae3278b4820b0ab2797feb1e7d8cc864df585dfb5ebe02a993325a9ad5e2d7d49d3132cf66013898351d044e0fe908ccdfeeebf651983601e3673a1f92d36510c0cc19b2e75856db8e4a41f92a51efa66d6cc22e414944c2c34a5a89ccde0be76f51410824e330d8e7c613194338c93732e8aea651fca18bcf1ac1824340c5553aff1e58d4ab8d7c8842b4712021e517cd6c140f6743c69c7bee05b10a8f24050a8caa4f96d1664909c5a06",
+ "6e85c2f8e1fdc3aaeb969da1258cb504bbf0070cd03d23b3fb5ee08feea5ee2e0ee1c71a5d0f4f701b351f4e4b4d74cb1e2ae6184814f77b62d2f08134b7236ebf6b67d8a6c9f01b4248b30667c555f5d8646dbfe291151b23c9c9857e33a4d5c847be29a5ee7b402e03bac02d1a4319acc0dd8f25e9c7a266f5e5c896cc11b5b238df96a0963ae806cb277abc515c298a3e61a3036b177acf87a56ca4478c4c6d0d468913de602ec891318bbaf52c97a77c35c5b7d164816cf24e4c4b0b5f45853882f716d61eb947a45ce2efa78f1c70a918512af1ad536cbe6148083385b34e207f5f690d7a954021e4b5f4258a385fd8a87809a481f34202af4caccb82",
+ "1e9b2c454e9de3a2d723d850331037dbf54133dbe27488ff757dd255833a27d8eb8a128ad12d0978b6884e25737086a704fb289aaaccf930d5b582ab4df1f55f0c429b6875edec3fe45464fa74164be056a55e243c4222c586bec5b18f39036aa903d98180f24f83d09a454dfa1e03a60e6a3ba4613e99c35f874d790174ee48a557f4f021ade4d1b278d7997ef094569b37b3db0505951e9ee8400adaea275c6db51b325ee730c69df97745b556ae41cd98741e28aa3a49544541eeb3da1b1e8fa4e8e9100d66dd0c7f5e2c271b1ecc077de79c462b9fe4c273543ecd82a5bea63c5acc01eca5fb780c7d7c8c9fe208ae8bd50cad1769693d92c6c8649d20d8",
+}
diff --git a/crypto/blake2b/blake2x.go b/crypto/blake2b/blake2x.go
new file mode 100644
index 0000000000..52c414db0e
--- /dev/null
+++ b/crypto/blake2b/blake2x.go
@@ -0,0 +1,177 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+ "encoding/binary"
+ "errors"
+ "io"
+)
+
+// XOF defines the interface to hash functions that
+// support arbitrary-length output.
+type XOF interface {
+ // Write absorbs more data into the hash's state. It panics if called
+ // after Read.
+ io.Writer
+
+ // Read reads more output from the hash. It returns io.EOF if the limit
+ // has been reached.
+ io.Reader
+
+ // Clone returns a copy of the XOF in its current state.
+ Clone() XOF
+
+ // Reset resets the XOF to its initial state.
+ Reset()
+}
+
+// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
+// the length of the output is not known in advance.
+const OutputLengthUnknown = 0
+
+// magicUnknownOutputLength is a magic value for the output size that indicates
+// an unknown number of output bytes.
+const magicUnknownOutputLength = (1 << 32) - 1
+
+// maxOutputLength is the absolute maximum number of bytes to produce when the
+// number of output bytes is unknown.
+const maxOutputLength = (1 << 32) * 64
+
+// NewXOF creates a new variable-output-length hash. The hash either produce a
+// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes
+// (size == OutputLengthUnknown). In the latter case, an absolute limit of
+// 256GiB applies.
+//
+// A non-nil key turns the hash into a MAC. The key must between
+// zero and 32 bytes long.
+func NewXOF(size uint32, key []byte) (XOF, error) {
+ if len(key) > Size {
+ return nil, errKeySize
+ }
+ if size == magicUnknownOutputLength {
+ // 2^32-1 indicates an unknown number of bytes and thus isn't a
+ // valid length.
+ return nil, errors.New("blake2b: XOF length too large")
+ }
+ if size == OutputLengthUnknown {
+ size = magicUnknownOutputLength
+ }
+ x := &xof{
+ d: digest{
+ size: Size,
+ keyLen: len(key),
+ },
+ length: size,
+ }
+ copy(x.d.key[:], key)
+ x.Reset()
+ return x, nil
+}
+
+type xof struct {
+ d digest
+ length uint32
+ remaining uint64
+ cfg, root, block [Size]byte
+ offset int
+ nodeOffset uint32
+ readMode bool
+}
+
+func (x *xof) Write(p []byte) (n int, err error) {
+ if x.readMode {
+ panic("blake2b: write to XOF after read")
+ }
+ return x.d.Write(p)
+}
+
+func (x *xof) Clone() XOF {
+ clone := *x
+ return &clone
+}
+
+func (x *xof) Reset() {
+ x.cfg[0] = byte(Size)
+ binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
+ binary.LittleEndian.PutUint32(x.cfg[12:], x.length) // XOF length
+ x.cfg[17] = byte(Size) // inner hash size
+
+ x.d.Reset()
+ x.d.h[1] ^= uint64(x.length) << 32
+
+ x.remaining = uint64(x.length)
+ if x.remaining == magicUnknownOutputLength {
+ x.remaining = maxOutputLength
+ }
+ x.offset, x.nodeOffset = 0, 0
+ x.readMode = false
+}
+
+func (x *xof) Read(p []byte) (n int, err error) {
+ if !x.readMode {
+ x.d.finalize(&x.root)
+ x.readMode = true
+ }
+
+ if x.remaining == 0 {
+ return 0, io.EOF
+ }
+
+ n = len(p)
+ if uint64(n) > x.remaining {
+ n = int(x.remaining)
+ p = p[:n]
+ }
+
+ if x.offset > 0 {
+ blockRemaining := Size - x.offset
+ if n < blockRemaining {
+ x.offset += copy(p, x.block[x.offset:])
+ x.remaining -= uint64(n)
+ return
+ }
+ copy(p, x.block[x.offset:])
+ p = p[blockRemaining:]
+ x.offset = 0
+ x.remaining -= uint64(blockRemaining)
+ }
+
+ for len(p) >= Size {
+ binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+ x.nodeOffset++
+
+ x.d.initConfig(&x.cfg)
+ x.d.Write(x.root[:])
+ x.d.finalize(&x.block)
+
+ copy(p, x.block[:])
+ p = p[Size:]
+ x.remaining -= uint64(Size)
+ }
+
+ if todo := len(p); todo > 0 {
+ if x.remaining < uint64(Size) {
+ x.cfg[0] = byte(x.remaining)
+ }
+ binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+ x.nodeOffset++
+
+ x.d.initConfig(&x.cfg)
+ x.d.Write(x.root[:])
+ x.d.finalize(&x.block)
+
+ x.offset = copy(p, x.block[:todo])
+ x.remaining -= uint64(todo)
+ }
+ return
+}
+
+func (d *digest) initConfig(cfg *[Size]byte) {
+ d.offset, d.c[0], d.c[1] = 0, 0, 0
+ for i := range d.h {
+ d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:])
+ }
+}
diff --git a/crypto/blake2b/register.go b/crypto/blake2b/register.go
new file mode 100644
index 0000000000..efd689af4b
--- /dev/null
+++ b/crypto/blake2b/register.go
@@ -0,0 +1,32 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.9
+
+package blake2b
+
+import (
+ "crypto"
+ "hash"
+)
+
+func init() {
+ newHash256 := func() hash.Hash {
+ h, _ := New256(nil)
+ return h
+ }
+ newHash384 := func() hash.Hash {
+ h, _ := New384(nil)
+ return h
+ }
+
+ newHash512 := func() hash.Hash {
+ h, _ := New512(nil)
+ return h
+ }
+
+ crypto.RegisterHash(crypto.BLAKE2b_256, newHash256)
+ crypto.RegisterHash(crypto.BLAKE2b_384, newHash384)
+ crypto.RegisterHash(crypto.BLAKE2b_512, newHash512)
+}
diff --git a/crypto/bn256/bn256_fast.go b/crypto/bn256/bn256_fast.go
index a8dfa8f67d..be0264a730 100644
--- a/crypto/bn256/bn256_fast.go
+++ b/crypto/bn256/bn256_fast.go
@@ -19,7 +19,7 @@
// Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve.
package bn256
-import "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
+import "github.com/XinFinOrg/XDPoSChain/crypto/bn256/cloudflare"
// G1 is an abstract cyclic group. The zero value is suitable for use as the
// output of an operation, but cannot be used as an input.
diff --git a/crypto/bn256/bn256_fuzz.go b/crypto/bn256/bn256_fuzz.go
index f360b0541f..eec0858466 100644
--- a/crypto/bn256/bn256_fuzz.go
+++ b/crypto/bn256/bn256_fuzz.go
@@ -22,8 +22,8 @@ import (
"bytes"
"math/big"
- cloudflare "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
- google "github.com/ethereum/go-ethereum/crypto/bn256/google"
+ cloudflare "github.com/XinFinOrg/XDPoSChain/crypto/bn256/cloudflare"
+ google "github.com/XinFinOrg/XDPoSChain/crypto/bn256/google"
)
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
diff --git a/crypto/bn256/bn256_slow.go b/crypto/bn256/bn256_slow.go
index 61373763b8..cf1053562d 100644
--- a/crypto/bn256/bn256_slow.go
+++ b/crypto/bn256/bn256_slow.go
@@ -19,7 +19,7 @@
// Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve.
package bn256
-import "github.com/ethereum/go-ethereum/crypto/bn256/google"
+import "github.com/XinFinOrg/XDPoSChain/crypto/bn256/google"
// G1 is an abstract cyclic group. The zero value is suitable for use as the
// output of an operation, but cannot be used as an input.
diff --git a/crypto/bn256/cloudflare/main_test.go b/crypto/bn256/cloudflare/main_test.go
index 0230f1b199..c0c85457be 100644
--- a/crypto/bn256/cloudflare/main_test.go
+++ b/crypto/bn256/cloudflare/main_test.go
@@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) {
t.Error(err)
continue
}
- t.Logf("%d: %x\n", n, g2.Marshal())
+ t.Logf("%v: %x\n", n, g2.Marshal())
}
}
diff --git a/crypto/bn256/google/main_test.go b/crypto/bn256/google/main_test.go
index 0230f1b199..c0c85457be 100644
--- a/crypto/bn256/google/main_test.go
+++ b/crypto/bn256/google/main_test.go
@@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) {
t.Error(err)
continue
}
- t.Logf("%d: %x\n", n, g2.Marshal())
+ t.Logf("%v: %x\n", n, g2.Marshal())
}
}
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 1c4d5a2e02..d978110c2c 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -28,10 +28,10 @@ import (
"math/big"
"os"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/crypto/sha3"
+ "github.com/XinFinOrg/XDPoSChain/rlp"
)
var (
@@ -74,6 +74,12 @@ func CreateAddress(b common.Address, nonce uint64) common.Address {
return common.BytesToAddress(Keccak256(data)[12:])
}
+// CreateAddress2 creates an ethereum address given the address bytes, initial
+// contract code hash and a salt.
+func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
+ return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
+}
+
// ToECDSA creates a private key with the given D value.
func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
return toECDSA(d, true)
diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go
index 8350354623..97fe96eda3 100644
--- a/crypto/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -25,7 +25,7 @@ import (
"os"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/XinFinOrg/XDPoSChain/common"
)
var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
diff --git a/crypto/ecies/ecies_test.go b/crypto/ecies/ecies_test.go
index f33f204d5b..15f5b392e5 100644
--- a/crypto/ecies/ecies_test.go
+++ b/crypto/ecies/ecies_test.go
@@ -35,21 +35,20 @@ import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
- "flag"
"fmt"
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/XinFinOrg/XDPoSChain/crypto"
)
-var dumpEnc bool
-
-func init() {
- flDump := flag.Bool("dump", false, "write encrypted test message to file")
- flag.Parse()
- dumpEnc = *flDump
-}
+//var dumpEnc bool
+//
+//func init() {
+// flDump := flag.Bool("dump", false, "write encrypted test message to file")
+// flag.Parse()
+// dumpEnc = *flDump
+//}
// Ensure the KDF generates appropriately sized keys.
func TestKDF(t *testing.T) {
@@ -58,12 +57,10 @@ func TestKDF(t *testing.T) {
k, err := concatKDF(h, msg, nil, 64)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
if len(k) != 64 {
- fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", len(k))
- t.FailNow()
+ t.Fatalf("KDF: generated key is the wrong size (%d instead of 64\n", len(k))
}
}
@@ -110,8 +107,7 @@ func cmpPrivate(prv1, prv2 *PrivateKey) bool {
func TestSharedKey(t *testing.T) {
prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2
@@ -164,7 +160,7 @@ func TestSharedKeyPadding(t *testing.T) {
// test shared secret generation
sk1, err := prv0.GenerateShared(&prv1.PublicKey, 16, 16)
if err != nil {
- fmt.Println(err.Error())
+ t.Log(err.Error())
}
sk2, err := prv1.GenerateShared(&prv0.PublicKey, 16, 16)
@@ -182,26 +178,22 @@ func TestSharedKeyPadding(t *testing.T) {
func TestTooBigSharedKey(t *testing.T) {
prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
_, err = prv1.GenerateShared(&prv2.PublicKey, 32, 32)
if err != ErrSharedKeyTooBig {
- fmt.Println("ecdh: shared key should be too large for curve")
- t.FailNow()
+ t.Fatal(err)
}
_, err = prv2.GenerateShared(&prv1.PublicKey, 32, 32)
if err != ErrSharedKeyTooBig {
- fmt.Println("ecdh: shared key should be too large for curve")
- t.FailNow()
+ t.Fatal(err)
}
}
@@ -209,8 +201,7 @@ func TestTooBigSharedKey(t *testing.T) {
func BenchmarkGenerateKeyP256(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil {
- fmt.Println(err.Error())
- b.FailNow()
+ b.Fatal(err)
}
}
}
@@ -219,15 +210,13 @@ func BenchmarkGenerateKeyP256(b *testing.B) {
func BenchmarkGenSharedKeyP256(b *testing.B) {
prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil)
if err != nil {
- fmt.Println(err.Error())
- b.FailNow()
+ b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := prv.GenerateShared(&prv.PublicKey, 16, 16)
if err != nil {
- fmt.Println(err.Error())
- b.FailNow()
+ b.Fatal(err)
}
}
}
@@ -236,15 +225,13 @@ func BenchmarkGenSharedKeyP256(b *testing.B) {
func BenchmarkGenSharedKeyS256(b *testing.B) {
prv, err := GenerateKey(rand.Reader, crypto.S256(), nil)
if err != nil {
- fmt.Println(err.Error())
- b.FailNow()
+ b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := prv.GenerateShared(&prv.PublicKey, 16, 16)
if err != nil {
- fmt.Println(err.Error())
- b.FailNow()
+ b.Fatal(err)
}
}
}
@@ -253,38 +240,32 @@ func BenchmarkGenSharedKeyS256(b *testing.B) {
func TestEncryptDecrypt(t *testing.T) {
prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
message := []byte("Hello, world.")
ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
pt, err := prv2.Decrypt(ct, nil, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
if !bytes.Equal(pt, message) {
- fmt.Println("ecies: plaintext doesn't match message")
- t.FailNow()
+ t.Fatal("ecies: plaintext doesn't match message")
}
_, err = prv1.Decrypt(ct, nil, nil)
if err == nil {
- fmt.Println("ecies: encryption should not have succeeded")
- t.FailNow()
+ t.Fatal("ecies: encryption should not have succeeded")
}
}
@@ -354,50 +335,39 @@ func TestParamSelection(t *testing.T) {
func testParamSelection(t *testing.T, c testCase) {
params := ParamsFromCurve(c.Curve)
if params == nil && c.Expected != nil {
- fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name)
- t.FailNow()
+ t.Fatalf("%s (%s)\n", ErrInvalidParams.Error(), c.Name)
} else if params != nil && !cmpParams(params, c.Expected) {
- fmt.Printf("ecies: parameters should be invalid (%s)\n",
- c.Name)
- t.FailNow()
+ t.Fatalf("ecies: parameters should be invalid (%s)\n", c.Name)
}
prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Printf("%s (%s)\n", err.Error(), c.Name)
- t.FailNow()
+ t.Fatalf("%s (%s)\n", err.Error(), c.Name)
}
prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Printf("%s (%s)\n", err.Error(), c.Name)
- t.FailNow()
+ t.Fatalf("%s (%s)\n", err.Error(), c.Name)
}
message := []byte("Hello, world.")
ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
if err != nil {
- fmt.Printf("%s (%s)\n", err.Error(), c.Name)
- t.FailNow()
+ t.Fatalf("%s (%s)\n", err.Error(), c.Name)
}
pt, err := prv2.Decrypt(ct, nil, nil)
if err != nil {
- fmt.Printf("%s (%s)\n", err.Error(), c.Name)
- t.FailNow()
+ t.Fatalf("%s (%s)\n", err.Error(), c.Name)
}
if !bytes.Equal(pt, message) {
- fmt.Printf("ecies: plaintext doesn't match message (%s)\n",
- c.Name)
- t.FailNow()
+ t.Fatalf("ecies: plaintext doesn't match message (%s)\n", c.Name)
}
_, err = prv1.Decrypt(ct, nil, nil)
if err == nil {
- fmt.Printf("ecies: encryption should not have succeeded (%s)\n",
- c.Name)
- t.FailNow()
+ t.Fatalf("ecies: encryption should not have succeeded (%s)\n", c.Name)
}
}
@@ -409,23 +379,20 @@ func TestBasicKeyValidation(t *testing.T) {
prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
message := []byte("Hello, world.")
ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
for _, b := range badBytes {
ct[0] = b
_, err := prv.Decrypt(ct, nil, nil)
if err != ErrInvalidPublicKey {
- fmt.Println("ecies: validated an invalid key")
- t.FailNow()
+ t.Fatal("ecies: validated an invalid key")
}
}
}
@@ -463,19 +430,16 @@ func TestSharedKeyStatic(t *testing.T) {
sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen)
if err != nil {
- fmt.Println(err.Error())
- t.FailNow()
+ t.Fatal(err)
}
if !bytes.Equal(sk1, sk2) {
- fmt.Println(ErrBadSharedKeys.Error())
- t.FailNow()
+ t.Fatal(ErrBadSharedKeys)
}
sk, _ := hex.DecodeString("167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62")
diff --git a/crypto/ecies/params.go b/crypto/ecies/params.go
index 6312daf5a1..969cc4a3bd 100644
--- a/crypto/ecies/params.go
+++ b/crypto/ecies/params.go
@@ -42,7 +42,7 @@ import (
"fmt"
"hash"
- ethcrypto "github.com/ethereum/go-ethereum/crypto"
+ ethcrypto "github.com/XinFinOrg/XDPoSChain/crypto"
)
var (
diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go
index df80481857..a12752e77b 100644
--- a/crypto/secp256k1/curve.go
+++ b/crypto/secp256k1/curve.go
@@ -36,7 +36,7 @@ import (
"math/big"
"unsafe"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
/*
diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go
index f6582ecd54..f8902607b9 100644
--- a/crypto/secp256k1/secp256_test.go
+++ b/crypto/secp256k1/secp256_test.go
@@ -24,8 +24,8 @@ import (
"encoding/hex"
"testing"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/randentropy"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/crypto/randentropy"
)
const TestCount = 1000
diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go
index 340bfc221e..665a20429a 100644
--- a/crypto/signature_cgo.go
+++ b/crypto/signature_cgo.go
@@ -23,8 +23,8 @@ import (
"crypto/elliptic"
"fmt"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
+ "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
)
// Ecrecover returns the uncompressed public key that created the given signature.
diff --git a/crypto/signature_test.go b/crypto/signature_test.go
index aecff76bfb..3d3331f4d7 100644
--- a/crypto/signature_test.go
+++ b/crypto/signature_test.go
@@ -22,9 +22,9 @@ import (
"reflect"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "github.com/XinFinOrg/XDPoSChain/common/hexutil"
+ "github.com/XinFinOrg/XDPoSChain/common/math"
)
var (
diff --git a/dashboard/README.md b/dashboard/README.md
deleted file mode 100644
index 641c5f44bc..0000000000
--- a/dashboard/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-## Go Ethereum Dashboard
-
-The dashboard is a data visualizer integrated into geth, intended to collect and visualize useful information of an Ethereum node. It consists of two parts:
-
-* The client visualizes the collected data.
-* The server collects the data, and updates the clients.
-
-The client's UI uses [React][React] with JSX syntax, which is validated by the [ESLint][ESLint] linter mostly according to the [Airbnb React/JSX Style Guide][Airbnb]. The style is defined in the `.eslintrc` configuration file. The resources are bundled into a single `bundle.js` file using [Webpack][Webpack], which relies on the `webpack.config.js`. The bundled file is referenced from `dashboard.html` and takes part in the `assets.go` too. The necessary dependencies for the module bundler are gathered by [Node.js][Node.js].
-
-### Development and bundling
-
-As the dashboard depends on certain NPM packages (which are not included in the `go-ethereum` repo), these need to be installed first:
-
-```
-$ (cd dashboard/assets && yarn install && yarn flow)
-```
-
-Normally the dashboard assets are bundled into Geth via `go-bindata` to avoid external dependencies. Rebuilding Geth after each UI modification however is not feasible from a developer perspective. Instead, we can run `yarn dev` to watch for file system changes and refresh the browser automatically.
-
-```
-$ geth --dashboard --vmodule=dashboard=5
-$ (cd dashboard/assets && yarn dev)
-```
-
-To bundle up the final UI into Geth, run `go generate`:
-
-```
-$ (cd dashboard && go generate)
-```
-
-### Static type checking
-
-Since JavaScript doesn't provide type safety, [Flow][Flow] is used to check types. These are only useful during development, so at the end of the process Babel will strip them.
-
-To take advantage of static type checking, your IDE needs to be prepared for it. In case of [Atom][Atom] a configuration guide can be found [here][Atom config]: Install the [Nuclide][Nuclide] package for Flow support, making sure it installs all of its support packages by enabling `Install Recommended Packages on Startup`, and set the path of the `flow-bin` which were installed previously by `yarn`.
-
-For more IDE support install the `linter-eslint` package too, which finds the `.eslintrc` file, and provides real-time linting. Atom warns, that these two packages are incompatible, but they seem to work well together. For third-party library errors and auto-completion [flow-typed][flow-typed] is used.
-
-### Have fun
-
-[Webpack][Webpack] offers handy tools for visualizing the bundle's dependency tree and space usage.
-
-* Generate the bundle's profile running `yarn stats`
-* For the _dependency tree_ go to [Webpack Analyze][WA], and import `stats.json`
-* For the _space usage_ go to [Webpack Visualizer][WV], and import `stats.json`
-
-[React]: https://reactjs.org/
-[ESLint]: https://eslint.org/
-[Airbnb]: https://github.com/airbnb/javascript/tree/master/react
-[Webpack]: https://webpack.github.io/
-[WA]: http://webpack.github.io/analyse/
-[WV]: http://chrisbateman.github.io/webpack-visualizer/
-[Node.js]: https://nodejs.org/en/
-[Flow]: https://flow.org/
-[Atom]: https://atom.io/
-[Atom config]: https://medium.com/@fastphrase/integrating-flow-into-a-react-project-fbbc2f130eed
-[Nuclide]: https://nuclide.io/docs/quick-start/getting-started/
-[flow-typed]: https://github.com/flowtype/flow-typed
diff --git a/dashboard/assets.go b/dashboard/assets.go
deleted file mode 100644
index 1304a3dba1..0000000000
--- a/dashboard/assets.go
+++ /dev/null
@@ -1,38624 +0,0 @@
-// Code generated by go-bindata. DO NOT EDIT.
-// sources:
-// assets/index.html
-// assets/bundle.js
-
-package dashboard
-
-import (
- "crypto/sha256"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
-)
-
-type asset struct {
- bytes []byte
- info os.FileInfo
- digest [sha256.Size]byte
-}
-
-type bindataFileInfo struct {
- name string
- size int64
- mode os.FileMode
- modTime time.Time
-}
-
-func (fi bindataFileInfo) Name() string {
- return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
- return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
- return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
- return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
- return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
- return nil
-}
-
-//nolint:misspell
-var _indexHtml = []byte(`
-
-
-
-
-
-
- Go Ethereum Dashboard
-
-
-
-
-
-
-
-
-`)
-
-func indexHtmlBytes() ([]byte, error) {
- return _indexHtml, nil
-}
-
-func indexHtml() (*asset, error) {
- bytes, err := indexHtmlBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "index.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
- a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6b, 0xd9, 0xa6, 0xeb, 0x32, 0x49, 0x9b, 0xe5, 0x3a, 0xcb, 0x99, 0xd3, 0xb6, 0x69, 0x7f, 0xde, 0x35, 0x9d, 0x5, 0x96, 0x84, 0xc0, 0x14, 0xef, 0xbe, 0x58, 0x10, 0x5e, 0x40, 0xf2, 0x12, 0x97}}
- return a, nil
-}
-
-//nolint:misspell
-var _bundleJs = []byte((((((((((`!function(modules) {
- function __webpack_require__(moduleId) {
- if (installedModules[moduleId]) return installedModules[moduleId].exports;
- var module = installedModules[moduleId] = {
- i: moduleId,
- l: !1,
- exports: {}
- };
- return modules[moduleId].call(module.exports, module, module.exports, __webpack_require__),
- module.l = !0, module.exports;
- }
- var installedModules = {};
- __webpack_require__.m = modules, __webpack_require__.c = installedModules, __webpack_require__.d = function(exports, name, getter) {
- __webpack_require__.o(exports, name) || Object.defineProperty(exports, name, {
- configurable: !1,
- enumerable: !0,
- get: getter
- });
- }, __webpack_require__.n = function(module) {
- var getter = module && module.__esModule ? function() {
- return module.default;
- } : function() {
- return module;
- };
- return __webpack_require__.d(getter, "a", getter), getter;
- }, __webpack_require__.o = function(object, property) {
- return Object.prototype.hasOwnProperty.call(object, property);
- }, __webpack_require__.p = "", __webpack_require__(__webpack_require__.s = 336);
-}([ function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- "production" === process.env.NODE_ENV ? module.exports = __webpack_require__(337) : module.exports = __webpack_require__(338);
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- (function(process) {
- if ("production" !== process.env.NODE_ENV) {
- var REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103, isValidElement = function(object) {
- return "object" == typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
- };
- module.exports = __webpack_require__(379)(isValidElement, !0);
- } else module.exports = __webpack_require__(380)();
- }).call(exports, __webpack_require__(2));
-}, function(module, exports) {
- function defaultSetTimout() {
- throw new Error("setTimeout has not been defined");
- }
- function defaultClearTimeout() {
- throw new Error("clearTimeout has not been defined");
- }
- function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) return setTimeout(fun, 0);
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) return cachedSetTimeout = setTimeout,
- setTimeout(fun, 0);
- try {
- return cachedSetTimeout(fun, 0);
- } catch (e) {
- try {
- return cachedSetTimeout.call(null, fun, 0);
- } catch (e) {
- return cachedSetTimeout.call(this, fun, 0);
- }
- }
- }
- function runClearTimeout(marker) {
- if (cachedClearTimeout === clearTimeout) return clearTimeout(marker);
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) return cachedClearTimeout = clearTimeout,
- clearTimeout(marker);
- try {
- return cachedClearTimeout(marker);
- } catch (e) {
- try {
- return cachedClearTimeout.call(null, marker);
- } catch (e) {
- return cachedClearTimeout.call(this, marker);
- }
- }
- }
- function cleanUpNextTick() {
- draining && currentQueue && (draining = !1, currentQueue.length ? queue = currentQueue.concat(queue) : queueIndex = -1,
- queue.length && drainQueue());
- }
- function drainQueue() {
- if (!draining) {
- var timeout = runTimeout(cleanUpNextTick);
- draining = !0;
- for (var len = queue.length; len; ) {
- for (currentQueue = queue, queue = []; ++queueIndex < len; ) currentQueue && currentQueue[queueIndex].run();
- queueIndex = -1, len = queue.length;
- }
- currentQueue = null, draining = !1, runClearTimeout(timeout);
- }
- }
- function Item(fun, array) {
- this.fun = fun, this.array = array;
- }
- function noop() {}
- var cachedSetTimeout, cachedClearTimeout, process = module.exports = {};
- !function() {
- try {
- cachedSetTimeout = "function" == typeof setTimeout ? setTimeout : defaultSetTimout;
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
- }
- try {
- cachedClearTimeout = "function" == typeof clearTimeout ? clearTimeout : defaultClearTimeout;
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
- }
- }();
- var currentQueue, queue = [], draining = !1, queueIndex = -1;
- process.nextTick = function(fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) for (var i = 1; i < arguments.length; i++) args[i - 1] = arguments[i];
- queue.push(new Item(fun, args)), 1 !== queue.length || draining || runTimeout(drainQueue);
- }, Item.prototype.run = function() {
- this.fun.apply(null, this.array);
- }, process.title = "browser", process.browser = !0, process.env = {}, process.argv = [],
- process.version = "", process.versions = {}, process.on = noop, process.addListener = noop,
- process.once = noop, process.off = noop, process.removeListener = noop, process.removeAllListeners = noop,
- process.emit = noop, process.prependListener = noop, process.prependOnceListener = noop,
- process.listeners = function(name) {
- return [];
- }, process.binding = function(name) {
- throw new Error("process.binding is not supported");
- }, process.cwd = function() {
- return "/";
- }, process.chdir = function(dir) {
- throw new Error("process.chdir is not supported");
- }, process.umask = function() {
- return 0;
- };
-}, function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
- !function() {
- "use strict";
- function classNames() {
- for (var classes = [], i = 0; i < arguments.length; i++) {
- var arg = arguments[i];
- if (arg) {
- var argType = typeof arg;
- if ("string" === argType || "number" === argType) classes.push(arg); else if (Array.isArray(arg)) classes.push(classNames.apply(null, arg)); else if ("object" === argType) for (var key in arg) hasOwn.call(arg, key) && arg[key] && classes.push(key);
- }
- }
- return classes.join(" ");
- }
- var hasOwn = {}.hasOwnProperty;
- void 0 !== module && module.exports ? module.exports = classNames : (__WEBPACK_AMD_DEFINE_ARRAY__ = [],
- void 0 !== (__WEBPACK_AMD_DEFINE_RESULT__ = function() {
- return classNames;
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }();
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _toConsumableArray(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- return Array.from(arr);
- }
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- __webpack_require__.d(__webpack_exports__, "c", function() {
- return PRESENTATION_ATTRIBUTES;
- }), __webpack_require__.d(__webpack_exports__, "a", function() {
- return EVENT_ATTRIBUTES;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return SCALE_TYPES;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return LEGEND_TYPES;
- }), __webpack_require__.d(__webpack_exports__, "j", function() {
- return getDisplayName;
- }), __webpack_require__.d(__webpack_exports__, "h", function() {
- return findAllByType;
- }), __webpack_require__.d(__webpack_exports__, "i", function() {
- return findChildByType;
- }), __webpack_require__.d(__webpack_exports__, "k", function() {
- return getPresentationAttributes;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return filterEventAttributes;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return filterEventsOfChild;
- }), __webpack_require__.d(__webpack_exports__, "q", function() {
- return validateWidthHeight;
- }), __webpack_require__.d(__webpack_exports__, "n", function() {
- return isSsr;
- }), __webpack_require__.d(__webpack_exports__, "g", function() {
- return filterSvgElements;
- }), __webpack_require__.d(__webpack_exports__, "m", function() {
- return isChildrenEqual;
- }), __webpack_require__.d(__webpack_exports__, "p", function() {
- return renderByOrder;
- }), __webpack_require__.d(__webpack_exports__, "l", function() {
- return getReactEventByType;
- }), __webpack_require__.d(__webpack_exports__, "o", function() {
- return parseChildIndex;
- });
- var __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_1_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isString__), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_8__PureRender__ = __webpack_require__(5), PRESENTATION_ATTRIBUTES = {
- alignmentBaseline: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- angle: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- baselineShift: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- clip: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- clipPath: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- clipRule: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- color: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- colorInterpolation: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- colorInterpolationFilters: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- colorProfile: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- colorRendering: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- cursor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- direction: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "ltr", "rtl", "inherit" ]),
- display: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- dominantBaseline: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- enableBackground: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- fill: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- fillOpacity: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number ]),
- fillRule: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "nonzero", "evenodd", "inherit" ]),
- filter: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- floodColor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- floodOpacity: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number ]),
- font: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- fontFamily: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- fontSize: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- fontSizeAdjust: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- fontStretch: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "inherit" ]),
- fontStyle: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "normal", "italic", "oblique", "inherit" ]),
- fontVariant: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "normal", "small-caps", "inherit" ]),
- fontWeight: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "normal", "bold", "bolder", "lighter", 100, 200, 300, 400, 500, 600, 700, 800, 900, "inherit" ]),
- glyphOrientationHorizontal: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- glyphOrientationVertical: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- imageRendering: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "auto", "optimizeSpeed", "optimizeQuality", "inherit" ]),
- kerning: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- letterSpacing: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- lightingColor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- markerEnd: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- markerMid: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- markerStart: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- mask: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- opacity: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- overflow: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "visible", "hidden", "scroll", "auto", "inherit" ]),
- pointerEvents: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "visiblePainted", "visibleFill", "visibleStroke", "visible", "painted", "fill", "stroke", "all", "none", "inherit" ]),
- shapeRendering: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "auto", "optimizeSpeed", "crispEdges", "geometricPrecision", "inherit" ]),
- stopColor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- stopOpacity: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- stroke: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- strokeDasharray: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- strokeDashoffset: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- strokeLinecap: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "butt", "round", "square", "inherit" ]),
- strokeLinejoin: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "miter", "round", "bevel", "inherit" ]),
- strokeMiterlimit: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- strokeOpacity: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- strokeWidth: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- textAnchor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "start", "middle", "end", "inherit" ]),
- textDecoration: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "none", "underline", "overline", "line-through", "blink", "inherit" ]),
- textRendering: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision", "inherit" ]),
- unicodeBidi: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "normal", "embed", "bidi-override", "inherit" ]),
- visibility: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "visible", "hidden", "collapse", "inherit" ]),
- wordSpacing: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- writingMode: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "lr-tb", "rl-tb", "tb-rl", "lr", "rl", "tb", "inherit" ]),
- transform: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- style: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.object,
- width: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- dx: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- dy: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- x: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- y: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- r: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- radius: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.array ])
- }, EVENT_ATTRIBUTES = {
- onClick: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseDown: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseUp: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseOver: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseMove: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseOut: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseEnter: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseLeave: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onTouchEnd: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onTouchMove: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onTouchStart: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onTouchCancel: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func
- }, REACT_BROWSER_EVENT_MAP = {
- click: "onClick",
- mousedown: "onMouseDown",
- mouseup: "onMouseUp",
- mouseover: "onMouseOver",
- mousemove: "onMouseMove",
- mouseout: "onMouseOut",
- mouseenter: "onMouseEnter",
- mouseleave: "onMouseLeave",
- touchcancel: "onTouchCancel",
- touchend: "onTouchEnd",
- touchmove: "onTouchMove",
- touchstart: "onTouchStart"
- }, SCALE_TYPES = [ "auto", "linear", "pow", "sqrt", "log", "identity", "time", "band", "point", "ordinal", "quantile", "quantize", "utcTime", "sequential", "threshold" ], LEGEND_TYPES = [ "plainline", "line", "square", "rect", "circle", "cross", "diamond", "star", "triangle", "wye", "none" ], getDisplayName = function(Comp) {
- return Comp ? "string" == typeof Comp ? Comp : Comp.displayName || Comp.name || "Component" : "";
- }, findAllByType = function(children, type) {
- var result = [], types = [];
- return types = __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(type) ? type.map(function(t) {
- return getDisplayName(t);
- }) : [ getDisplayName(type) ], __WEBPACK_IMPORTED_MODULE_5_react___default.a.Children.forEach(children, function(child) {
- var childType = child && child.type && (child.type.displayName || child.type.name);
- -1 !== types.indexOf(childType) && result.push(child);
- }), result;
- }, findChildByType = function(children, type) {
- var result = findAllByType(children, type);
- return result && result[0];
- }, getPresentationAttributes = function(el) {
- if (!el || __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default()(el)) return null;
- var props = __WEBPACK_IMPORTED_MODULE_5_react___default.a.isValidElement(el) ? el.props : el;
- if (!__WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default()(props)) return null;
- var out = null;
- for (var i in props) ({}).hasOwnProperty.call(props, i) && PRESENTATION_ATTRIBUTES[i] && (out || (out = {}),
- out[i] = props[i]);
- return out;
- }, getEventHandlerOfElement = function(originalHandler, props) {
- return function(e) {
- return originalHandler(props, e), null;
- };
- }, filterEventAttributes = function(el, newHandler) {
- var wrapCallback = arguments.length > 2 && void 0 !== arguments[2] && arguments[2];
- if (!el || __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default()(el)) return null;
- var props = __WEBPACK_IMPORTED_MODULE_5_react___default.a.isValidElement(el) ? el.props : el;
- if (!__WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default()(props)) return null;
- var out = null;
- for (var i in props) ({}).hasOwnProperty.call(props, i) && EVENT_ATTRIBUTES[i] && (out || (out = {}),
- out[i] = newHandler || (wrapCallback ? getEventHandlerOfElement(props[i], props) : props[i]));
- return out;
- }, getEventHandlerOfChild = function(originalHandler, data, index) {
- return function(e) {
- return originalHandler(data, index, e), null;
- };
- }, filterEventsOfChild = function(props, data, index) {
- if (!__WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default()(props)) return null;
- var out = null;
- for (var i in props) ({}).hasOwnProperty.call(props, i) && EVENT_ATTRIBUTES[i] && __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default()(props[i]) && (out || (out = {}),
- out[i] = getEventHandlerOfChild(props[i], data, index));
- return out;
- }, validateWidthHeight = function(el) {
- if (!el || !el.props) return !1;
- var _el$props = el.props, width = _el$props.width, height = _el$props.height;
- return !(!Object(__WEBPACK_IMPORTED_MODULE_7__DataUtils__.h)(width) || width <= 0 || !Object(__WEBPACK_IMPORTED_MODULE_7__DataUtils__.h)(height) || height <= 0);
- }, isSsr = function() {
- return !("undefined" != typeof window && window.document && window.document.createElement && window.setTimeout);
- }, SVG_TAGS = [ "a", "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColormatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-url", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "lineGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tref", "tspan", "use", "view", "vkern" ], isSvgElement = function(child) {
- return child && child.type && __WEBPACK_IMPORTED_MODULE_1_lodash_isString___default()(child.type) && SVG_TAGS.indexOf(child.type) >= 0;
- }, filterSvgElements = function(children) {
- var svgElements = [];
- return __WEBPACK_IMPORTED_MODULE_5_react___default.a.Children.forEach(children, function(entry) {
- entry && entry.type && __WEBPACK_IMPORTED_MODULE_1_lodash_isString___default()(entry.type) && SVG_TAGS.indexOf(entry.type) >= 0 && svgElements.push(entry);
- }), svgElements;
- }, isSingleChildEqual = function(nextChild, prevChild) {
- if (__WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(nextChild) && __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(prevChild)) return !0;
- if (!__WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(nextChild) && !__WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(prevChild)) {
- var _ref = nextChild.props || {}, nextChildren = _ref.children, nextProps = _objectWithoutProperties(_ref, [ "children" ]), _ref2 = prevChild.props || {}, prevChildren = _ref2.children, prevProps = _objectWithoutProperties(_ref2, [ "children" ]);
- return nextChildren && prevChildren ? Object(__WEBPACK_IMPORTED_MODULE_8__PureRender__.b)(nextProps, prevProps) && isChildrenEqual(nextChildren, prevChildren) : !nextChildren && !prevChildren && Object(__WEBPACK_IMPORTED_MODULE_8__PureRender__.b)(nextProps, prevProps);
- }
- return !1;
- }, isChildrenEqual = function isChildrenEqual(nextChildren, prevChildren) {
- if (nextChildren === prevChildren) return !0;
- if (__WEBPACK_IMPORTED_MODULE_5_react__.Children.count(nextChildren) !== __WEBPACK_IMPORTED_MODULE_5_react__.Children.count(prevChildren)) return !1;
- var count = __WEBPACK_IMPORTED_MODULE_5_react__.Children.count(nextChildren);
- if (0 === count) return !0;
- if (1 === count) return isSingleChildEqual(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(nextChildren) ? nextChildren[0] : nextChildren, __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(prevChildren) ? prevChildren[0] : prevChildren);
- for (var i = 0; i < count; i++) {
- var nextChild = nextChildren[i], prevChild = prevChildren[i];
- if (__WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(nextChild) || __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(prevChild)) {
- if (!isChildrenEqual(nextChild, prevChild)) return !1;
- } else if (!isSingleChildEqual(nextChild, prevChild)) return !1;
- }
- return !0;
- }, renderByOrder = function(children, renderMap) {
- var elements = [], record = {};
- return __WEBPACK_IMPORTED_MODULE_5_react__.Children.forEach(children, function(child, index) {
- if (child && isSvgElement(child)) elements.push(child); else if (child && renderMap[getDisplayName(child.type)]) {
- var displayName = getDisplayName(child.type), _renderMap$displayNam = renderMap[displayName], handler = _renderMap$displayNam.handler, once = _renderMap$displayNam.once;
- if (once && !record[displayName] || !once) {
- var results = handler(child, displayName, index);
- __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(results) ? elements = [ elements ].concat(_toConsumableArray(results)) : elements.push(results),
- record[displayName] = !0;
- }
- }
- }), elements;
- }, getReactEventByType = function(e) {
- var type = e && e.type;
- return type && REACT_BROWSER_EVENT_MAP[type] ? REACT_BROWSER_EVENT_MAP[type] : null;
- }, parseChildIndex = function(child, children) {
- var result = -1;
- return __WEBPACK_IMPORTED_MODULE_5_react__.Children.forEach(children, function(entry, index) {
- entry === child && (result = index);
- }), result;
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function shallowEqual(a, b) {
- for (var key in a) if ({}.hasOwnProperty.call(a, key) && (!{}.hasOwnProperty.call(b, key) || a[key] !== b[key])) return !1;
- for (var _key in b) if ({}.hasOwnProperty.call(b, _key) && !{}.hasOwnProperty.call(a, _key)) return !1;
- return !0;
- }
- function shouldComponentUpdate(props, state) {
- return !shallowEqual(props, this.props) || !shallowEqual(state, this.state);
- }
- function pureRenderDecorator(component) {
- component.prototype.shouldComponentUpdate = shouldComponentUpdate;
- }
- __webpack_exports__.b = shallowEqual, __webpack_exports__.a = pureRenderDecorator;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0;
- var _assign = __webpack_require__(204), _assign2 = function(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }(_assign);
- exports.default = _assign2.default || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0, exports.default = function(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- };
-}, function(module, exports, __webpack_require__) {
- function isFunction(value) {
- if (!isObject(value)) return !1;
- var tag = baseGetTag(value);
- return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
- }
- var baseGetTag = __webpack_require__(41), isObject = __webpack_require__(31), asyncTag = "[object AsyncFunction]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
- module.exports = isFunction;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_require__.d(__webpack_exports__, "j", function() {
- return mathSign;
- }), __webpack_require__.d(__webpack_exports__, "i", function() {
- return isPercent;
- }), __webpack_require__.d(__webpack_exports__, "h", function() {
- return isNumber;
- }), __webpack_require__.d(__webpack_exports__, "g", function() {
- return isNumOrStr;
- }), __webpack_require__.d(__webpack_exports__, "k", function() {
- return uniqueId;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return getPercentValue;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return getAnyElementOfObject;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return hasDuplicate;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return interpolateNumber;
- }), __webpack_require__.d(__webpack_exports__, "a", function() {
- return findEntryInArray;
- }), __webpack_require__.d(__webpack_exports__, "c", function() {
- return getLinearRegression;
- });
- var __WEBPACK_IMPORTED_MODULE_0_lodash_get__ = __webpack_require__(164), __WEBPACK_IMPORTED_MODULE_0_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_get__), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(116), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__ = __webpack_require__(169), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__), __WEBPACK_IMPORTED_MODULE_4_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isString__), mathSign = function(value) {
- return 0 === value ? 0 : value > 0 ? 1 : -1;
- }, isPercent = function(value) {
- return __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default()(value) && value.indexOf("%") === value.length - 1;
- }, isNumber = function(value) {
- return __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber___default()(value) && !__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default()(value);
- }, isNumOrStr = function(value) {
- return isNumber(value) || __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default()(value);
- }, idCounter = 0, uniqueId = function(prefix) {
- var id = ++idCounter;
- return "" + (prefix || "") + id;
- }, getPercentValue = function(percent, totalValue) {
- var defaultValue = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 0, validate = arguments.length > 3 && void 0 !== arguments[3] && arguments[3];
- if (!isNumber(percent) && !__WEBPACK_IMPORTED_MODULE_4_lodash_isString___default()(percent)) return defaultValue;
- var value = void 0;
- if (isPercent(percent)) {
- var index = percent.indexOf("%");
- value = totalValue * parseFloat(percent.slice(0, index)) / 100;
- } else value = +percent;
- return __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default()(value) && (value = defaultValue),
- validate && value > totalValue && (value = totalValue), value;
- }, getAnyElementOfObject = function(obj) {
- if (!obj) return null;
- var keys = Object.keys(obj);
- return keys && keys.length ? obj[keys[0]] : null;
- }, hasDuplicate = function(ary) {
- if (!__WEBPACK_IMPORTED_MODULE_1_lodash_isArray___default()(ary)) return !1;
- for (var len = ary.length, cache = {}, i = 0; i < len; i++) {
- if (cache[ary[i]]) return !0;
- cache[ary[i]] = !0;
- }
- return !1;
- }, interpolateNumber = function(numberA, numberB) {
- return isNumber(numberA) && isNumber(numberB) ? function(t) {
- return numberA + t * (numberB - numberA);
- } : function() {
- return numberB;
- };
- }, findEntryInArray = function(ary, specifiedKey, specifiedValue) {
- return ary && ary.length ? ary.find(function(entry) {
- return entry && __WEBPACK_IMPORTED_MODULE_0_lodash_get___default()(entry, specifiedKey) === specifiedValue;
- }) : null;
- }, getLinearRegression = function(data) {
- if (!data || !data.length) return null;
- for (var len = data.length, xsum = 0, ysum = 0, xysum = 0, xxsum = 0, xmin = 1 / 0, xmax = -1 / 0, i = 0; i < len; i++) xsum += data[i].cx,
- ysum += data[i].cy, xysum += data[i].cx * data[i].cy, xxsum += data[i].cx * data[i].cx,
- xmin = Math.min(xmin, data[i].cx), xmax = Math.max(xmax, data[i].cx);
- var a = len * xxsum != xsum * xsum ? (len * xysum - xsum * ysum) / (len * xxsum - xsum * xsum) : 0;
- return {
- xmin: xmin,
- xmax: xmax,
- a: a,
- b: (ysum - a * xsum) / len
- };
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function getDefaultTheme() {
- return defaultTheme || (defaultTheme = (0, _createMuiTheme2.default)());
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- }), exports.sheetsManager = void 0;
- var _keys = __webpack_require__(50), _keys2 = _interopRequireDefault(_keys), _extends2 = __webpack_require__(6), _extends3 = _interopRequireDefault(_extends2), _getPrototypeOf = __webpack_require__(26), _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf), _classCallCheck2 = __webpack_require__(27), _classCallCheck3 = _interopRequireDefault(_classCallCheck2), _createClass2 = __webpack_require__(28), _createClass3 = _interopRequireDefault(_createClass2), _possibleConstructorReturn2 = __webpack_require__(29), _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2), _inherits2 = __webpack_require__(30), _inherits3 = _interopRequireDefault(_inherits2), _objectWithoutProperties2 = __webpack_require__(7), _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2), _map = __webpack_require__(401), _map2 = _interopRequireDefault(_map), _minSafeInteger = __webpack_require__(417), _minSafeInteger2 = _interopRequireDefault(_minSafeInteger), _react = __webpack_require__(0), _react2 = _interopRequireDefault(_react), _propTypes = __webpack_require__(1), _propTypes2 = _interopRequireDefault(_propTypes), _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning), _hoistNonReactStatics = __webpack_require__(151), _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics), _getDisplayName = __webpack_require__(226), _getDisplayName2 = _interopRequireDefault(_getDisplayName), _wrapDisplayName = __webpack_require__(75), _wrapDisplayName2 = _interopRequireDefault(_wrapDisplayName), _contextTypes = __webpack_require__(420), _contextTypes2 = _interopRequireDefault(_contextTypes), _jss = __webpack_require__(228), _ns = __webpack_require__(227), ns = function(obj) {
- if (obj && obj.__esModule) return obj;
- var newObj = {};
- if (null != obj) for (var key in obj) Object.prototype.hasOwnProperty.call(obj, key) && (newObj[key] = obj[key]);
- return newObj.default = obj, newObj;
- }(_ns), _jssPreset = __webpack_require__(442), _jssPreset2 = _interopRequireDefault(_jssPreset), _createMuiTheme = __webpack_require__(150), _createMuiTheme2 = _interopRequireDefault(_createMuiTheme), _themeListener = __webpack_require__(149), _themeListener2 = _interopRequireDefault(_themeListener), _createGenerateClassName = __webpack_require__(455), _createGenerateClassName2 = _interopRequireDefault(_createGenerateClassName), _getStylesCreator = __webpack_require__(456), _getStylesCreator2 = _interopRequireDefault(_getStylesCreator), jss = (0,
- _jss.create)((0, _jssPreset2.default)()), generateClassName = (0, _createGenerateClassName2.default)(), indexCounter = _minSafeInteger2.default, sheetsManager = exports.sheetsManager = new _map2.default(), noopTheme = {}, defaultTheme = void 0, withStyles = function(stylesOrCreator) {
- var options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
- return function(Component) {
- var _options$withTheme = options.withTheme, withTheme = void 0 !== _options$withTheme && _options$withTheme, _options$flip = options.flip, flip = void 0 === _options$flip ? null : _options$flip, name = options.name, styleSheetOptions = (0,
- _objectWithoutProperties3.default)(options, [ "withTheme", "flip", "name" ]), stylesCreator = (0,
- _getStylesCreator2.default)(stylesOrCreator), listenToTheme = stylesCreator.themingEnabled || withTheme || "string" == typeof name;
- indexCounter += 1, stylesCreator.options.index = indexCounter, "production" !== process.env.NODE_ENV && (0,
- _warning2.default)(indexCounter < 0, [ "Material-UI: you might have a memory leak.", "The indexCounter is not supposed to grow that much." ].join(" "));
- var WithStyles = function(_React$Component) {
- function WithStyles(props, context) {
- (0, _classCallCheck3.default)(this, WithStyles);
- var _this = (0, _possibleConstructorReturn3.default)(this, (WithStyles.__proto__ || (0,
- _getPrototypeOf2.default)(WithStyles)).call(this, props, context));
- _this.state = {}, _this.disableStylesGeneration = !1, _this.jss = null, _this.sheetOptions = null,
- _this.sheetsManager = sheetsManager, _this.stylesCreatorSaved = null, _this.theme = null,
- _this.unsubscribeId = null, _this.jss = _this.context[ns.jss] || jss;
- var muiThemeProviderOptions = _this.context.muiThemeProviderOptions;
- return muiThemeProviderOptions && (muiThemeProviderOptions.sheetsManager && (_this.sheetsManager = muiThemeProviderOptions.sheetsManager),
- _this.disableStylesGeneration = muiThemeProviderOptions.disableStylesGeneration),
- _this.stylesCreatorSaved = stylesCreator, _this.sheetOptions = (0, _extends3.default)({
- generateClassName: generateClassName
- }, _this.context[ns.sheetOptions]), _this.theme = listenToTheme ? _themeListener2.default.initial(context) || getDefaultTheme() : noopTheme,
- _this;
- }
- return (0, _inherits3.default)(WithStyles, _React$Component), (0, _createClass3.default)(WithStyles, [ {
- key: "componentWillMount",
- value: function() {
- this.attach(this.theme);
- }
- }, {
- key: "componentDidMount",
- value: function() {
- var _this2 = this;
- listenToTheme && (this.unsubscribeId = _themeListener2.default.subscribe(this.context, function(theme) {
- var oldTheme = _this2.theme;
- _this2.theme = theme, _this2.attach(_this2.theme), _this2.setState({}, function() {
- _this2.detach(oldTheme);
- });
- }));
- }
- }, {
- key: "componentWillReceiveProps",
- value: function() {
- this.stylesCreatorSaved !== stylesCreator && "production" !== process.env.NODE_ENV && (this.detach(this.theme),
- this.stylesCreatorSaved = stylesCreator, this.attach(this.theme));
- }
- }, {
- key: "componentWillUnmount",
- value: function() {
- this.detach(this.theme), null !== this.unsubscribeId && _themeListener2.default.unsubscribe(this.context, this.unsubscribeId);
- }
- }, {
- key: "attach",
- value: function(theme) {
- if (!this.disableStylesGeneration) {
- var stylesCreatorSaved = this.stylesCreatorSaved, sheetManager = this.sheetsManager.get(stylesCreatorSaved);
- sheetManager || (sheetManager = new _map2.default(), this.sheetsManager.set(stylesCreatorSaved, sheetManager));
- var sheetManagerTheme = sheetManager.get(theme);
- if (sheetManagerTheme || (sheetManagerTheme = {
- refs: 0,
- sheet: null
- }, sheetManager.set(theme, sheetManagerTheme)), 0 === sheetManagerTheme.refs) {
- var styles = stylesCreatorSaved.create(theme, name), meta = name;
- "production" === process.env.NODE_ENV || meta || (meta = (0, _getDisplayName2.default)(Component));
- var sheet = this.jss.createStyleSheet(styles, (0, _extends3.default)({
- meta: meta,
- classNamePrefix: meta,
- flip: "boolean" == typeof flip ? flip : "rtl" === theme.direction,
- link: !1
- }, this.sheetOptions, stylesCreatorSaved.options, {
- name: name
- }, styleSheetOptions));
- sheetManagerTheme.sheet = sheet, sheet.attach();
- var sheetsRegistry = this.context[ns.sheetsRegistry];
- sheetsRegistry && sheetsRegistry.add(sheet);
- }
- sheetManagerTheme.refs += 1;
- }
- }
- }, {
- key: "detach",
- value: function(theme) {
- if (!this.disableStylesGeneration) {
- var stylesCreatorSaved = this.stylesCreatorSaved, sheetManager = this.sheetsManager.get(stylesCreatorSaved), sheetManagerTheme = sheetManager.get(theme);
- if (sheetManagerTheme.refs -= 1, 0 === sheetManagerTheme.refs) {
- sheetManager.delete(theme), this.jss.removeStyleSheet(sheetManagerTheme.sheet);
- var sheetsRegistry = this.context[ns.sheetsRegistry];
- sheetsRegistry && sheetsRegistry.remove(sheetManagerTheme.sheet);
- }
- }
- }
- }, {
- key: "render",
- value: function() {
- var _this3 = this, _props = this.props, classesProp = _props.classes, innerRef = _props.innerRef, other = (0,
- _objectWithoutProperties3.default)(_props, [ "classes", "innerRef" ]), classes = void 0, renderedClasses = {};
- if (!this.disableStylesGeneration) {
- var sheetManager = this.sheetsManager.get(this.stylesCreatorSaved), sheetsManagerTheme = sheetManager.get(this.theme);
- renderedClasses = sheetsManagerTheme.sheet.classes;
- }
- classes = classesProp ? (0, _extends3.default)({}, renderedClasses, (0, _keys2.default)(classesProp).reduce(function(accumulator, key) {
- return "production" !== process.env.NODE_ENV && (0, _warning2.default)(renderedClasses[key] || _this3.disableStylesGeneration, [ "Material-UI: the key ` + "`") + (`" + key + "` + ("`" + ` provided to the classes property is not implemented in " + (0,
- _getDisplayName2.default)(Component) + ".", "You can only override one of the following: " + (0,
- _keys2.default)(renderedClasses).join(",") ].join("\n")), "production" !== process.env.NODE_ENV && (0,
- _warning2.default)(!classesProp[key] || "string" == typeof classesProp[key], [ "Material-UI: the key `))) + (("`" + (`" + key + "` + "`")) + (` provided to the classes property is not valid for " + (0,
- _getDisplayName2.default)(Component) + ".", "You need to provide a non empty string instead of: " + classesProp[key] + "." ].join("\n")),
- classesProp[key] && (accumulator[key] = renderedClasses[key] + " " + classesProp[key]),
- accumulator;
- }, {})) : renderedClasses;
- var more = {};
- return withTheme && (more.theme = this.theme), _react2.default.createElement(Component, (0,
- _extends3.default)({
- classes: classes
- }, more, other, {
- ref: innerRef
- }));
- }
- } ]), WithStyles;
- }(_react2.default.Component);
- return WithStyles.propTypes = "production" !== process.env.NODE_ENV ? {
- classes: _propTypes2.default.object,
- innerRef: _propTypes2.default.func
- } : {}, WithStyles.contextTypes = (0, _extends3.default)({
- muiThemeProviderOptions: _propTypes2.default.object
- }, _contextTypes2.default, listenToTheme ? _themeListener2.default.contextTypes : {}),
- "production" !== process.env.NODE_ENV && (WithStyles.displayName = (0, _wrapDisplayName2.default)(Component, "WithStyles")),
- (0, _hoistNonReactStatics2.default)(WithStyles, Component), "production" !== process.env.NODE_ENV && (WithStyles.Naked = Component,
- WithStyles.options = options), WithStyles;
- };
- };
- exports.default = withStyles;
- }).call(exports, __webpack_require__(2));
-}, function(module, exports) {
- var isArray = Array.isArray;
- module.exports = isArray;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- var warning = function() {};
- "production" !== process.env.NODE_ENV && (warning = function(condition, format, args) {
- var len = arguments.length;
- args = new Array(len > 2 ? len - 2 : 0);
- for (var key = 2; key < len; key++) args[key - 2] = arguments[key];
- if (void 0 === format) throw new Error("` + ("`" + `warning(condition, format, ...args)`)))) + ((("`" + (` requires a warning message argument");
- if (format.length < 10 || /^[s\W]*$/.test(format)) throw new Error("The warning format should be able to uniquely identify this warning. Please, use a more descriptive format than: " + format);
- if (!condition) {
- var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() {
- return args[argIndex++];
- });
- "undefined" != typeof console && console.error(message);
- try {
- throw new Error(message);
- } catch (x) {}
- }
- }), module.exports = warning;
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0;
- var _defineProperty = __webpack_require__(142), _defineProperty2 = function(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }(_defineProperty);
- exports.default = function(obj, key, value) {
- return key in obj ? (0, _defineProperty2.default)(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }) : obj[key] = value, obj;
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function Layer(props) {
- var children = props.children, className = props.className, others = _objectWithoutProperties(props, [ "children", "className" ]), layerClass = __WEBPACK_IMPORTED_MODULE_2_classnames___default()("recharts-layer", className);
- return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("g", _extends({
- className: layerClass
- }, others), children);
- }
- var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_2_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_classnames__), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, propTypes = {
- className: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- children: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node), __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node ])
- };
- Layer.propTypes = propTypes, __webpack_exports__.a = Layer;
-}, function(module, exports, __webpack_require__) {
- var global = __webpack_require__(157), core = __webpack_require__(158), hide = __webpack_require__(245), redefine = __webpack_require__(536), ctx = __webpack_require__(539), $export = function(type, name, source) {
- var key, own, out, exp, IS_FORCED = type & $export.F, IS_GLOBAL = type & $export.G, IS_STATIC = type & $export.S, IS_PROTO = type & $export.P, IS_BIND = type & $export.B, target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {}).prototype, exports = IS_GLOBAL ? core : core[name] || (core[name] = {}), expProto = exports.prototype || (exports.prototype = {});
- IS_GLOBAL && (source = name);
- for (key in source) own = !IS_FORCED && target && void 0 !== target[key], out = (own ? target : source)[key],
- exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && "function" == typeof out ? ctx(Function.call, out) : out,
- target && redefine(target, key, out, type & $export.U), exports[key] != out && hide(exports, key, exp),
- IS_PROTO && expProto[key] != out && (expProto[key] = out);
- };
- global.core = core, $export.F = 1, $export.G = 2, $export.S = 4, $export.P = 8,
- $export.B = 16, $export.W = 32, $export.U = 64, $export.R = 128, module.exports = $export;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _defineProperty(obj, key, value) {
- return key in obj ? Object.defineProperty(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }) : obj[key] = value, obj;
- }
- function _toConsumableArray(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- return Array.from(arr);
- }
- __webpack_require__.d(__webpack_exports__, "w", function() {
- return getValueByDataKey;
- }), __webpack_require__.d(__webpack_exports__, "n", function() {
- return getDomainOfDataByKey;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return calculateActiveTickIndex;
- }), __webpack_require__.d(__webpack_exports__, "r", function() {
- return getMainColorOfGraphicItem;
- }), __webpack_require__.d(__webpack_exports__, "q", function() {
- return getLegendProps;
- }), __webpack_require__.d(__webpack_exports__, "i", function() {
- return getBarSizeList;
- }), __webpack_require__.d(__webpack_exports__, "h", function() {
- return getBarPosition;
- }), __webpack_require__.d(__webpack_exports__, "a", function() {
- return appendOffsetOfLegend;
- }), __webpack_require__.d(__webpack_exports__, "z", function() {
- return parseErrorBarsOfAxis;
- }), __webpack_require__.d(__webpack_exports__, "o", function() {
- return getDomainOfItemsWithSameAxis;
- }), __webpack_require__.d(__webpack_exports__, "x", function() {
- return isCategorialAxis;
- }), __webpack_require__.d(__webpack_exports__, "m", function() {
- return getCoordinatesOfGrid;
- }), __webpack_require__.d(__webpack_exports__, "u", function() {
- return getTicksOfAxis;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return combineEventHandlers;
- }), __webpack_require__.d(__webpack_exports__, "A", function() {
- return parseScale;
- }), __webpack_require__.d(__webpack_exports__, "c", function() {
- return checkDomainOfScale;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return findPositionOfBar;
- }), __webpack_require__.d(__webpack_exports__, "C", function() {
- return truncateByDomain;
- }), __webpack_require__.d(__webpack_exports__, "s", function() {
- return getStackGroupsByAxisId;
- }), __webpack_require__.d(__webpack_exports__, "v", function() {
- return getTicksOfScale;
- }), __webpack_require__.d(__webpack_exports__, "l", function() {
- return getCateCoordinateOfLine;
- }), __webpack_require__.d(__webpack_exports__, "k", function() {
- return getCateCoordinateOfBar;
- }), __webpack_require__.d(__webpack_exports__, "j", function() {
- return getBaseValueOfBar;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return detectReferenceElementsDomain;
- }), __webpack_require__.d(__webpack_exports__, "t", function() {
- return getStackedDataOfItem;
- }), __webpack_require__.d(__webpack_exports__, "p", function() {
- return getDomainOfStackGroups;
- }), __webpack_require__.d(__webpack_exports__, "B", function() {
- return parseSpecifiedDomain;
- }), __webpack_require__.d(__webpack_exports__, "D", function() {
- return validateCoordinateInRange;
- }), __webpack_require__.d(__webpack_exports__, "g", function() {
- return getBandSizeOfAxis;
- }), __webpack_require__.d(__webpack_exports__, "y", function() {
- return parseDomainOfCategoryAxis;
- });
- var __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__ = __webpack_require__(34), __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__ = __webpack_require__(284), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(116), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_3_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isString__), __WEBPACK_IMPORTED_MODULE_4_lodash_max__ = __webpack_require__(700), __WEBPACK_IMPORTED_MODULE_4_lodash_max___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_max__), __WEBPACK_IMPORTED_MODULE_5_lodash_min__ = __webpack_require__(289), __WEBPACK_IMPORTED_MODULE_5_lodash_min___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_lodash_min__), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__ = __webpack_require__(701), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_9_lodash_get__ = __webpack_require__(164), __WEBPACK_IMPORTED_MODULE_9_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_lodash_get__), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_11_recharts_scale__ = __webpack_require__(703), __WEBPACK_IMPORTED_MODULE_12_d3_scale__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_11_recharts_scale__),
- __webpack_require__(292)), __WEBPACK_IMPORTED_MODULE_13_d3_shape__ = __webpack_require__(172), __WEBPACK_IMPORTED_MODULE_14__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_15__cartesian_ReferenceDot__ = __webpack_require__(325), __WEBPACK_IMPORTED_MODULE_16__cartesian_ReferenceLine__ = __webpack_require__(326), __WEBPACK_IMPORTED_MODULE_17__cartesian_ReferenceArea__ = __webpack_require__(327), __WEBPACK_IMPORTED_MODULE_18__cartesian_ErrorBar__ = __webpack_require__(92), __WEBPACK_IMPORTED_MODULE_19__component_Legend__ = __webpack_require__(170), __WEBPACK_IMPORTED_MODULE_20__ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, getValueByDataKey = function(obj, dataKey, defaultValue) {
- return __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(obj) || __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(dataKey) ? defaultValue : Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.g)(dataKey) ? __WEBPACK_IMPORTED_MODULE_9_lodash_get___default()(obj, dataKey, defaultValue) : __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(dataKey) ? dataKey(obj) : defaultValue;
- }, getDomainOfDataByKey = function(data, key, type, filterNil) {
- var flattenData = __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap___default()(data, function(entry) {
- return getValueByDataKey(entry, key);
- });
- if ("number" === type) {
- var domain = flattenData.filter(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h);
- return [ Math.min.apply(null, domain), Math.max.apply(null, domain) ];
- }
- return (filterNil ? flattenData.filter(function(entry) {
- return !__WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(entry);
- }) : flattenData).map(function(entry) {
- return Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.g)(entry) ? entry : "";
- });
- }, calculateActiveTickIndex = function(coordinate, ticks, unsortedTicks, axis) {
- var index = -1, len = ticks.length;
- if (len > 1) {
- if (axis && "angleAxis" === axis.axisType && Math.abs(Math.abs(axis.range[1] - axis.range[0]) - 360) <= 1e-6) for (var range = axis.range, i = 0; i < len; i++) {
- var before = i > 0 ? unsortedTicks[i - 1].coordinate : unsortedTicks[len - 1].coordinate, cur = unsortedTicks[i].coordinate, after = i >= len - 1 ? unsortedTicks[0].coordinate : unsortedTicks[i + 1].coordinate, sameDirectionCoord = void 0;
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.j)(cur - before) !== Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.j)(after - cur)) {
- var diffInterval = [];
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.j)(after - cur) === Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.j)(range[1] - range[0])) {
- sameDirectionCoord = after;
- var curInRange = cur + range[1] - range[0];
- diffInterval[0] = Math.min(curInRange, (curInRange + before) / 2), diffInterval[1] = Math.max(curInRange, (curInRange + before) / 2);
- } else {
- sameDirectionCoord = before;
- var afterInRange = after + range[1] - range[0];
- diffInterval[0] = Math.min(cur, (afterInRange + cur) / 2), diffInterval[1] = Math.max(cur, (afterInRange + cur) / 2);
- }
- var sameInterval = [ Math.min(cur, (sameDirectionCoord + cur) / 2), Math.max(cur, (sameDirectionCoord + cur) / 2) ];
- if (coordinate > sameInterval[0] && coordinate <= sameInterval[1] || coordinate >= diffInterval[0] && coordinate <= diffInterval[1]) {
- index = unsortedTicks[i].index;
- break;
- }
- } else {
- var min = Math.min(before, after), max = Math.max(before, after);
- if (coordinate > (min + cur) / 2 && coordinate <= (max + cur) / 2) {
- index = unsortedTicks[i].index;
- break;
- }
- }
- } else for (var _i = 0; _i < len; _i++) if (0 === _i && coordinate <= (ticks[_i].coordinate + ticks[_i + 1].coordinate) / 2 || _i > 0 && _i < len - 1 && coordinate > (ticks[_i].coordinate + ticks[_i - 1].coordinate) / 2 && coordinate <= (ticks[_i].coordinate + ticks[_i + 1].coordinate) / 2 || _i === len - 1 && coordinate > (ticks[_i].coordinate + ticks[_i - 1].coordinate) / 2) {
- index = ticks[_i].index;
- break;
- }
- } else index = 0;
- return index;
- }, getMainColorOfGraphicItem = function(item) {
- var displayName = item.type.displayName, result = void 0;
- switch (displayName) {
- case "Line":
- case "Area":
- case "Radar":
- result = item.props.stroke;
- break;
-
- default:
- result = item.props.fill;
- }
- return result;
- }, getLegendProps = function(_ref) {
- var children = _ref.children, formatedGraphicalItems = _ref.formatedGraphicalItems, legendWidth = _ref.legendWidth, legendContent = _ref.legendContent, legendItem = Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_19__component_Legend__.a);
- if (!legendItem) return null;
- var legendData = void 0;
- return legendData = legendItem.props && legendItem.props.payload ? legendItem.props && legendItem.props.payload : "children" === legendContent ? (formatedGraphicalItems || []).reduce(function(result, _ref2) {
- var item = _ref2.item, props = _ref2.props, data = props.sectors || props.data || [];
- return result.concat(data.map(function(entry) {
- return {
- type: legendItem.props.iconType || item.props.legendType,
- value: entry.name,
- color: entry.fill,
- payload: entry
- };
- }));
- }, []) : (formatedGraphicalItems || []).map(function(_ref3) {
- var item = _ref3.item, _item$props = item.props, dataKey = _item$props.dataKey, name = _item$props.name, legendType = _item$props.legendType;
- return {
- inactive: _item$props.hide,
- dataKey: dataKey,
- type: legendItem.props.iconType || legendType || "square",
- color: getMainColorOfGraphicItem(item),
- value: name || dataKey,
- payload: item.props
- };
- }), _extends({}, legendItem.props, __WEBPACK_IMPORTED_MODULE_19__component_Legend__.a.getWithHeight(legendItem, legendWidth), {
- payload: legendData,
- item: legendItem
- });
- }, getBarSizeList = function(_ref4) {
- var globalSize = _ref4.barSize, _ref4$stackGroups = _ref4.stackGroups, stackGroups = void 0 === _ref4$stackGroups ? {} : _ref4$stackGroups;
- if (!stackGroups) return {};
- for (var result = {}, numericAxisIds = Object.keys(stackGroups), i = 0, len = numericAxisIds.length; i < len; i++) for (var sgs = stackGroups[numericAxisIds[i]].stackGroups, stackIds = Object.keys(sgs), j = 0, sLen = stackIds.length; j < sLen; j++) {
- var _sgs$stackIds$j = sgs[stackIds[j]], items = _sgs$stackIds$j.items, cateAxisId = _sgs$stackIds$j.cateAxisId, barItems = items.filter(function(item) {
- return Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.j)(item.type).indexOf("Bar") >= 0;
- });
- if (barItems && barItems.length) {
- var selfSize = barItems[0].props.barSize, cateId = barItems[0].props[cateAxisId];
- result[cateId] || (result[cateId] = []), result[cateId].push({
- item: barItems[0],
- stackList: barItems.slice(1),
- barSize: __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(selfSize) ? globalSize : selfSize
- });
- }
- }
- return result;
- }, getBarPosition = function(_ref5) {
- var barGap = _ref5.barGap, barCategoryGap = _ref5.barCategoryGap, bandSize = _ref5.bandSize, _ref5$sizeList = _ref5.sizeList, sizeList = void 0 === _ref5$sizeList ? [] : _ref5$sizeList, maxBarSize = _ref5.maxBarSize, len = sizeList.length;
- if (len < 1) return null;
- var realBarGap = Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.d)(barGap, bandSize, 0, !0), result = void 0;
- if (sizeList[0].barSize === +sizeList[0].barSize) {
- var useFull = !1, fullBarSize = bandSize / len, sum = sizeList.reduce(function(res, entry) {
- return res + entry.barSize || 0;
- }, 0);
- sum += (len - 1) * realBarGap, sum >= bandSize && (sum -= (len - 1) * realBarGap,
- realBarGap = 0), sum >= bandSize && fullBarSize > 0 && (useFull = !0, fullBarSize *= .9,
- sum = len * fullBarSize);
- var offset = (bandSize - sum) / 2 >> 0, prev = {
- offset: offset - realBarGap,
- size: 0
- };
- result = sizeList.reduce(function(res, entry) {
- var newRes = [].concat(_toConsumableArray(res), [ {
- item: entry.item,
- position: {
- offset: prev.offset + prev.size + realBarGap,
- size: useFull ? fullBarSize : entry.barSize
- }
- } ]);
- return prev = newRes[newRes.length - 1].position, entry.stackList && entry.stackList.length && entry.stackList.forEach(function(item) {
- newRes.push({
- item: item,
- position: prev
- });
- }), newRes;
- }, []);
- } else {
- var _offset = Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.d)(barCategoryGap, bandSize, 0, !0);
- bandSize - 2 * _offset - (len - 1) * realBarGap <= 0 && (realBarGap = 0);
- var originalSize = (bandSize - 2 * _offset - (len - 1) * realBarGap) / len;
- originalSize > 1 && (originalSize >>= 0);
- var size = maxBarSize === +maxBarSize ? Math.min(originalSize, maxBarSize) : originalSize;
- result = sizeList.reduce(function(res, entry, i) {
- var newRes = [].concat(_toConsumableArray(res), [ {
- item: entry.item,
- position: {
- offset: _offset + (originalSize + realBarGap) * i + (originalSize - size) / 2,
- size: size
- }
- } ]);
- return entry.stackList && entry.stackList.length && entry.stackList.forEach(function(item) {
- newRes.push({
- item: item,
- position: newRes[newRes.length - 1].position
- });
- }), newRes;
- }, []);
- }
- return result;
- }, appendOffsetOfLegend = function(offset, items, props, legendBox) {
- var children = props.children, width = props.width, height = props.height, margin = props.margin, legendWidth = width - (margin.left || 0) - (margin.right || 0), legendHeight = height - (margin.top || 0) - (margin.bottom || 0), legendProps = getLegendProps({
- children: children,
- items: items,
- legendWidth: legendWidth,
- legendHeight: legendHeight
- }), newOffset = offset;
- if (legendProps) {
- var box = legendBox || {}, align = legendProps.align, verticalAlign = legendProps.verticalAlign, layout = legendProps.layout;
- ("vertical" === layout || "horizontal" === layout && "center" === verticalAlign) && Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(offset[align]) && (newOffset = _extends({}, offset, _defineProperty({}, align, newOffset[align] + (box.width || 0)))),
- ("horizontal" === layout || "vertical" === layout && "center" === align) && Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(offset[verticalAlign]) && (newOffset = _extends({}, offset, _defineProperty({}, verticalAlign, newOffset[verticalAlign] + (box.height || 0))));
- }
- return newOffset;
- }, getDomainOfErrorBars = function(data, item, dataKey, axisType) {
- var children = item.props.children, errorBars = Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.h)(children, __WEBPACK_IMPORTED_MODULE_18__cartesian_ErrorBar__.a).filter(function(errorBarChild) {
- var direction = errorBarChild.props.direction;
- return !(!__WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(direction) && !__WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(axisType)) || axisType.indexOf(direction) >= 0;
- });
- if (errorBars && errorBars.length) {
- var keys = errorBars.map(function(errorBarChild) {
- return errorBarChild.props.dataKey;
- });
- return data.reduce(function(result, entry) {
- var entryValue = getValueByDataKey(entry, dataKey, 0), mainValue = __WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default()(entryValue) ? [ __WEBPACK_IMPORTED_MODULE_5_lodash_min___default()(entryValue), __WEBPACK_IMPORTED_MODULE_4_lodash_max___default()(entryValue) ] : [ entryValue, entryValue ], errorDomain = keys.reduce(function(prevErrorArr, k) {
- var errorValue = getValueByDataKey(entry, k, 0), lowerValue = mainValue[0] - Math.abs(__WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default()(errorValue) ? errorValue[0] : errorValue), upperValue = mainValue[1] + Math.abs(__WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default()(errorValue) ? errorValue[1] : errorValue);
- return [ Math.min(lowerValue, prevErrorArr[0]), Math.max(upperValue, prevErrorArr[1]) ];
- }, [ 1 / 0, -1 / 0 ]);
- return [ Math.min(errorDomain[0], result[0]), Math.max(errorDomain[1], result[1]) ];
- }, [ 1 / 0, -1 / 0 ]);
- }
- return null;
- }, parseErrorBarsOfAxis = function(data, items, dataKey, axisType) {
- var domains = items.map(function(item) {
- return getDomainOfErrorBars(data, item, dataKey, axisType);
- }).filter(function(entry) {
- return !__WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(entry);
- });
- return domains && domains.length ? domains.reduce(function(result, entry) {
- return [ Math.min(result[0], entry[0]), Math.max(result[1], entry[1]) ];
- }, [ 1 / 0, -1 / 0 ]) : null;
- }, getDomainOfItemsWithSameAxis = function(data, items, type, filterNil) {
- var domains = items.map(function(item) {
- var dataKey = item.props.dataKey;
- return "number" === type && dataKey ? getDomainOfErrorBars(data, item, dataKey) || getDomainOfDataByKey(data, dataKey, type, filterNil) : getDomainOfDataByKey(data, dataKey, type, filterNil);
- });
- if ("number" === type) return domains.reduce(function(result, entry) {
- return [ Math.min(result[0], entry[0]), Math.max(result[1], entry[1]) ];
- }, [ 1 / 0, -1 / 0 ]);
- var tag = {};
- return domains.reduce(function(result, entry) {
- for (var i = 0, len = entry.length; i < len; i++) tag[entry[i]] || (tag[entry[i]] = !0,
- result.push(entry[i]));
- return result;
- }, []);
- }, isCategorialAxis = function(layout, axisType) {
- return "horizontal" === layout && "xAxis" === axisType || "vertical" === layout && "yAxis" === axisType || "centric" === layout && "angleAxis" === axisType || "radial" === layout && "radiusAxis" === axisType;
- }, getCoordinatesOfGrid = function(ticks, min, max) {
- var hasMin = void 0, hasMax = void 0, values = ticks.map(function(entry) {
- return entry.coordinate === min && (hasMin = !0), entry.coordinate === max && (hasMax = !0),
- entry.coordinate;
- });
- return hasMin || values.push(min), hasMax || values.push(max), values;
- }, getTicksOfAxis = function(axis, isGrid, isAll) {
- if (!axis) return null;
- var scale = axis.scale, duplicateDomain = axis.duplicateDomain, type = axis.type, range = axis.range, offset = (isGrid || isAll) && "category" === type && scale.bandwidth ? scale.bandwidth() / 2 : 0;
- return offset = "angleAxis" === axis.axisType ? 2 * Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.j)(range[0] - range[1]) * offset : offset,
- isGrid && (axis.ticks || axis.niceTicks) ? (axis.ticks || axis.niceTicks).map(function(entry) {
- var scaleContent = duplicateDomain ? duplicateDomain.indexOf(entry) : entry;
- return {
- coordinate: scale(scaleContent) + offset,
- value: entry,
- offset: offset
- };
- }) : axis.isCategorial && axis.categoricalDomain ? axis.categoricalDomain.map(function(entry, index) {
- return {
- coordinate: scale(entry),
- value: entry,
- index: index,
- offset: offset
- };
- }) : scale.ticks && !isAll ? scale.ticks(axis.tickCount).map(function(entry) {
- return {
- coordinate: scale(entry) + offset,
- value: entry,
- offset: offset
- };
- }) : scale.domain().map(function(entry, index) {
- return {
- coordinate: scale(entry) + offset,
- value: duplicateDomain ? duplicateDomain[entry] : entry,
- index: index,
- offset: offset
- };
- });
- }, combineEventHandlers = function(defaultHandler, parentHandler, childHandler) {
- var customizedHandler = void 0;
- return __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(childHandler) ? customizedHandler = childHandler : __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(parentHandler) && (customizedHandler = parentHandler),
- __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(defaultHandler) || customizedHandler ? function(arg1, arg2, arg3, arg4) {
- __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(defaultHandler) && defaultHandler(arg1, arg2, arg3, arg4),
- __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(customizedHandler) && customizedHandler(arg1, arg2, arg3, arg4);
- } : null;
- }, parseScale = function(axis, chartType) {
- var scale = axis.scale, type = axis.type, layout = axis.layout, axisType = axis.axisType;
- if ("auto" === scale) return "radial" === layout && "radiusAxis" === axisType ? {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scaleBand(),
- realScaleType: "band"
- } : "radial" === layout && "angleAxis" === axisType ? {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scaleLinear(),
- realScaleType: "linear"
- } : "category" === type && chartType && (chartType.indexOf("LineChart") >= 0 || chartType.indexOf("AreaChart") >= 0) ? {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scalePoint(),
- realScaleType: "point"
- } : "category" === type ? {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scaleBand(),
- realScaleType: "band"
- } : {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scaleLinear(),
- realScaleType: "linear"
- };
- if (__WEBPACK_IMPORTED_MODULE_3_lodash_isString___default()(scale)) {
- var name = "scale" + scale.slice(0, 1).toUpperCase() + scale.slice(1);
- return {
- scale: (__WEBPACK_IMPORTED_MODULE_12_d3_scale__[name] || __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scalePoint)(),
- realScaleType: __WEBPACK_IMPORTED_MODULE_12_d3_scale__[name] ? name : "point"
- };
- }
- return __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(scale) ? {
- scale: scale
- } : {
- scale: __WEBPACK_IMPORTED_MODULE_12_d3_scale__.scalePoint(),
- realScaleType: "point"
- };
- }, checkDomainOfScale = function(scale) {
- var domain = scale.domain();
- if (domain && !(domain.length <= 2)) {
- var len = domain.length, range = scale.range(), min = Math.min(range[0], range[1]) - 1e-4, max = Math.max(range[0], range[1]) + 1e-4, first = scale(domain[0]), last = scale(domain[len - 1]);
- (first < min || first > max || last < min || last > max) && scale.domain([ domain[0], domain[len - 1] ]);
- }
- }, findPositionOfBar = function(barPosition, child) {
- if (!barPosition) return null;
- for (var i = 0, len = barPosition.length; i < len; i++) if (barPosition[i].item === child) return barPosition[i].position;
- return null;
- }, truncateByDomain = function(value, domain) {
- if (!domain || 2 !== domain.length || !Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(domain[0]) || !Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(domain[1])) return value;
- var min = Math.min(domain[0], domain[1]), max = Math.max(domain[0], domain[1]), result = [ value[0], value[1] ];
- return (!Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(value[0]) || value[0] < min) && (result[0] = min),
- (!Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(value[1]) || value[1] > max) && (result[1] = max),
- result[0] > max && (result[0] = max), result[1] < min && (result[1] = min), result;
- }, offsetSign = function(series) {
- var n = series.length;
- if (!(n <= 0)) for (var j = 0, m = series[0].length; j < m; ++j) for (var positive = 0, negative = 0, i = 0; i < n; ++i) {
- var value = __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default()(series[i][j][1]) ? series[i][j][0] : series[i][j][1];
- value >= 0 ? (series[i][j][0] = positive, series[i][j][1] = positive + value, positive = series[i][j][1]) : (series[i][j][0] = negative,
- series[i][j][1] = negative + value, negative = series[i][j][1]);
- }
- }, STACK_OFFSET_MAP = {
- sign: offsetSign,
- expand: __WEBPACK_IMPORTED_MODULE_13_d3_shape__.o,
- none: __WEBPACK_IMPORTED_MODULE_13_d3_shape__.p,
- silhouette: __WEBPACK_IMPORTED_MODULE_13_d3_shape__.q,
- wiggle: __WEBPACK_IMPORTED_MODULE_13_d3_shape__.r
- }, getStackedData = function(data, stackItems, offsetType) {
- var dataKeys = stackItems.map(function(item) {
- return item.props.dataKey;
- });
- return Object(__WEBPACK_IMPORTED_MODULE_13_d3_shape__.n)().keys(dataKeys).value(function(d, key) {
- return +getValueByDataKey(d, key, 0);
- }).order(__WEBPACK_IMPORTED_MODULE_13_d3_shape__.s).offset(STACK_OFFSET_MAP[offsetType])(data);
- }, getStackGroupsByAxisId = function(data, _items, numericAxisId, cateAxisId, offsetType, reverseStackOrder) {
- if (!data) return null;
- var items = reverseStackOrder ? _items.reverse() : _items, stackGroups = items.reduce(function(result, item) {
- var _item$props2 = item.props, stackId = _item$props2.stackId;
- if (_item$props2.hide) return result;
- var axisId = item.props[numericAxisId], parentGroup = result[axisId] || {
- hasStack: !1,
- stackGroups: {}
- };
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.g)(stackId)) {
- var childGroup = parentGroup.stackGroups[stackId] || {
- numericAxisId: numericAxisId,
- cateAxisId: cateAxisId,
- items: []
- };
- childGroup.items.push(item), parentGroup.hasStack = !0, parentGroup.stackGroups[stackId] = childGroup;
- } else parentGroup.stackGroups[Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.k)("_stackId_")] = {
- numericAxisId: numericAxisId,
- cateAxisId: cateAxisId,
- items: [ item ]
- };
- return _extends({}, result, _defineProperty({}, axisId, parentGroup));
- }, {});
- return Object.keys(stackGroups).reduce(function(result, axisId) {
- var group = stackGroups[axisId];
- return group.hasStack && (group.stackGroups = Object.keys(group.stackGroups).reduce(function(res, stackId) {
- var g = group.stackGroups[stackId];
- return _extends({}, res, _defineProperty({}, stackId, {
- numericAxisId: numericAxisId,
- cateAxisId: cateAxisId,
- items: g.items,
- stackedData: getStackedData(data, g.items, offsetType)
- }));
- }, {})), _extends({}, result, _defineProperty({}, axisId, group));
- }, {});
- }, calculateDomainOfTicks = function(ticks, type) {
- return "number" === type ? [ Math.min.apply(null, ticks), Math.max.apply(null, ticks) ] : ticks;
- }, getTicksOfScale = function(scale, opts) {
- var realScaleType = opts.realScaleType, type = opts.type, tickCount = opts.tickCount, originalDomain = opts.originalDomain, allowDecimals = opts.allowDecimals, scaleType = realScaleType || opts.scale;
- if ("auto" !== scaleType && "linear" !== scaleType) return null;
- if (tickCount && "number" === type && originalDomain && ("auto" === originalDomain[0] || "auto" === originalDomain[1])) {
- var domain = scale.domain(), tickValues = Object(__WEBPACK_IMPORTED_MODULE_11_recharts_scale__.getNiceTickValues)(domain, tickCount, allowDecimals);
- return scale.domain(calculateDomainOfTicks(tickValues, type)), {
- niceTicks: tickValues
- };
- }
- if (tickCount && "number" === type) {
- var _domain = scale.domain();
- return {
- niceTicks: Object(__WEBPACK_IMPORTED_MODULE_11_recharts_scale__.getTickValuesFixedDomain)(_domain, tickCount, allowDecimals)
- };
- }
- return null;
- }, getCateCoordinateOfLine = function(_ref6) {
- var axis = _ref6.axis, ticks = _ref6.ticks, bandSize = _ref6.bandSize, entry = _ref6.entry, index = _ref6.index;
- if ("category" === axis.type) {
- if (!axis.allowDuplicatedCategory && axis.dataKey && !__WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(entry[axis.dataKey])) {
- var matchedTick = Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.a)(ticks, "value", entry[axis.dataKey]);
- if (matchedTick) return matchedTick.coordinate + bandSize / 2;
- }
- return ticks[index] ? ticks[index].coordinate + bandSize / 2 : null;
- }
- var value = getValueByDataKey(entry, axis.dataKey);
- return __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(value) ? null : axis.scale(value);
- }, getCateCoordinateOfBar = function(_ref7) {
- var axis = _ref7.axis, ticks = _ref7.ticks, offset = _ref7.offset, bandSize = _ref7.bandSize, entry = _ref7.entry, index = _ref7.index;
- if ("category" === axis.type) return ticks[index] ? ticks[index].coordinate + offset : null;
- var value = getValueByDataKey(entry, axis.dataKey, axis.domain[index]);
- return __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default()(value) ? null : axis.scale(value) - bandSize / 2 + offset;
- }, getBaseValueOfBar = function(_ref8) {
- var numericAxis = _ref8.numericAxis, domain = numericAxis.scale.domain();
- if ("number" === numericAxis.type) {
- var min = Math.min(domain[0], domain[1]), max = Math.max(domain[0], domain[1]);
- return min <= 0 && max >= 0 ? 0 : max < 0 ? max : min;
- }
- return domain[0];
- }, detectReferenceElementsDomain = function(children, domain, axisId, axisType, specifiedTicks) {
- var lines = Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.h)(children, __WEBPACK_IMPORTED_MODULE_16__cartesian_ReferenceLine__.a), dots = Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.h)(children, __WEBPACK_IMPORTED_MODULE_15__cartesian_ReferenceDot__.a), elements = lines.concat(dots), areas = Object(__WEBPACK_IMPORTED_MODULE_20__ReactUtils__.h)(children, __WEBPACK_IMPORTED_MODULE_17__cartesian_ReferenceArea__.a), idKey = axisType + "Id", valueKey = axisType[0], finalDomain = domain;
- if (elements.length && (finalDomain = elements.reduce(function(result, el) {
- if (el.props[idKey] === axisId && el.props.alwaysShow && Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(el.props[valueKey])) {
- var value = el.props[valueKey];
- return [ Math.min(result[0], value), Math.max(result[1], value) ];
- }
- return result;
- }, finalDomain)), areas.length) {
- var key1 = valueKey + "1", key2 = valueKey + "2";
- finalDomain = areas.reduce(function(result, el) {
- if (el.props[idKey] === axisId && el.props.alwaysShow && Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(el.props[key1]) && Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(el.props[key2])) {
- var value1 = el.props[key1], value2 = el.props[key2];
- return [ Math.min(result[0], value1, value2), Math.max(result[1], value1, value2) ];
- }
- return result;
- }, finalDomain);
- }
- return specifiedTicks && specifiedTicks.length && (finalDomain = specifiedTicks.reduce(function(result, tick) {
- return Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(tick) ? [ Math.min(result[0], tick), Math.max(result[1], tick) ] : result;
- }, finalDomain)), finalDomain;
- }, getStackedDataOfItem = function(item, stackGroups) {
- var stackId = item.props.stackId;
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.g)(stackId)) {
- var group = stackGroups[stackId];
- if (group && group.items.length) {
- for (var itemIndex = -1, i = 0, len = group.items.length; i < len; i++) if (group.items[i] === item) {
- itemIndex = i;
- break;
- }
- return itemIndex >= 0 ? group.stackedData[itemIndex] : null;
- }
- }
- return null;
- }, getDomainOfSingle = function(data) {
- return data.reduce(function(result, entry) {
- return [ Math.min.apply(null, entry.concat([ result[0] ]).filter(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)), Math.max.apply(null, entry.concat([ result[1] ]).filter(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)) ];
- }, [ 1 / 0, -1 / 0 ]);
- }, getDomainOfStackGroups = function(stackGroups, startIndex, endIndex) {
- return Object.keys(stackGroups).reduce(function(result, stackId) {
- var group = stackGroups[stackId], stackedData = group.stackedData, domain = stackedData.reduce(function(res, entry) {
- var s = getDomainOfSingle(entry.slice(startIndex, endIndex + 1));
- return [ Math.min(res[0], s[0]), Math.max(res[1], s[1]) ];
- }, [ 1 / 0, -1 / 0 ]);
- return [ Math.min(domain[0], result[0]), Math.max(domain[1], result[1]) ];
- }, [ 1 / 0, -1 / 0 ]).map(function(result) {
- return result === 1 / 0 || result === -1 / 0 ? 0 : result;
- });
- }, MIN_VALUE_REG = /^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/, MAX_VALUE_REG = /^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/, parseSpecifiedDomain = function(specifiedDomain, dataDomain, allowDataOverflow) {
- if (!__WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default()(specifiedDomain)) return dataDomain;
- var domain = [];
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(specifiedDomain[0])) domain[0] = allowDataOverflow ? specifiedDomain[0] : Math.min(specifiedDomain[0], dataDomain[0]); else if (MIN_VALUE_REG.test(specifiedDomain[0])) {
- var value = +MIN_VALUE_REG.exec(specifiedDomain[0])[1];
- domain[0] = dataDomain[0] - value;
- } else __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(specifiedDomain[0]) ? domain[0] = specifiedDomain[0](dataDomain[0]) : domain[0] = dataDomain[0];
- if (Object(__WEBPACK_IMPORTED_MODULE_14__DataUtils__.h)(specifiedDomain[1])) domain[1] = allowDataOverflow ? specifiedDomain[1] : Math.max(specifiedDomain[1], dataDomain[1]); else if (MAX_VALUE_REG.test(specifiedDomain[1])) {
- var _value = +MAX_VALUE_REG.exec(specifiedDomain[1])[1];
- domain[1] = dataDomain[1] + _value;
- } else __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default()(specifiedDomain[1]) ? domain[1] = specifiedDomain[1](dataDomain[1]) : domain[1] = dataDomain[1];
- return domain;
- }, validateCoordinateInRange = function(coordinate, scale) {
- if (!scale) return !1;
- var range = scale.range(), first = range[0], last = range[range.length - 1];
- return first <= last ? coordinate >= first && coordinate <= last : coordinate >= last && coordinate <= first;
- }, getBandSizeOfAxis = function(axis, ticks) {
- if (axis && axis.scale && axis.scale.bandwidth) return axis.scale.bandwidth();
- if (axis && ticks && ticks.length >= 2) {
- for (var orderedTicks = __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy___default()(ticks, function(o) {
- return o.coordinate;
- }), bandSize = 1 / 0, i = 1, len = orderedTicks.length; i < len; i++) {
- var cur = orderedTicks[i], prev = orderedTicks[i - 1];
- bandSize = Math.min((cur.coordinate || 0) - (prev.coordinate || 0), bandSize);
- }
- return bandSize === 1 / 0 ? 0 : bandSize;
- }
- return 0;
- }, parseDomainOfCategoryAxis = function(specifiedDomain, calculatedDomain, axisChild) {
- return specifiedDomain && specifiedDomain.length ? __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual___default()(specifiedDomain, __WEBPACK_IMPORTED_MODULE_9_lodash_get___default()(axisChild, "type.defaultProps.domain")) ? calculatedDomain : specifiedDomain : calculatedDomain;
- };
-}, function(module, exports) {
- var core = module.exports = {
- version: "2.5.3"
- };
- "number" == typeof __e && (__e = core);
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function newInterval(floori, offseti, count, field) {
- function interval(date) {
- return floori(date = new Date(+date)), date;
- }
- return interval.floor = interval, interval.ceil = function(date) {
- return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
- }, interval.round = function(date) {
- var d0 = interval(date), d1 = interval.ceil(date);
- return date - d0 < d1 - date ? d0 : d1;
- }, interval.offset = function(date, step) {
- return offseti(date = new Date(+date), null == step ? 1 : Math.floor(step)), date;
- }, interval.range = function(start, stop, step) {
- var previous, range = [];
- if (start = interval.ceil(start), step = null == step ? 1 : Math.floor(step), !(start < stop && step > 0)) return range;
- do {
- range.push(previous = new Date(+start)), offseti(start, step), floori(start);
- } while (previous < start && start < stop);
- return range;
- }, interval.filter = function(test) {
- return newInterval(function(date) {
- if (date >= date) for (;floori(date), !test(date); ) date.setTime(date - 1);
- }, function(date, step) {
- if (date >= date) if (step < 0) for (;++step <= 0; ) for (;offseti(date, -1), !test(date); ) ; else for (;--step >= 0; ) for (;offseti(date, 1),
- !test(date); ) ;
- });
- }, count && (interval.count = function(start, end) {
- return t0.setTime(+start), t1.setTime(+end), floori(t0), floori(t1), Math.floor(count(t0, t1));
- }, interval.every = function(step) {
- return step = Math.floor(step), isFinite(step) && step > 0 ? step > 1 ? interval.filter(field ? function(d) {
- return field(d) % step == 0;
- } : function(d) {
- return interval.count(0, d) % step == 0;
- }) : interval : null;
- }), interval;
- }
- __webpack_exports__.a = newInterval;
- var t0 = new Date(), t1 = new Date();
-}, function(module, exports, __webpack_require__) {
- var global = __webpack_require__(24), core = __webpack_require__(17), ctx = __webpack_require__(46), hide = __webpack_require__(40), $export = function(type, name, source) {
- var key, own, out, IS_FORCED = type & $export.F, IS_GLOBAL = type & $export.G, IS_STATIC = type & $export.S, IS_PROTO = type & $export.P, IS_BIND = type & $export.B, IS_WRAP = type & $export.W, exports = IS_GLOBAL ? core : core[name] || (core[name] = {}), expProto = exports.prototype, target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {}).prototype;
- IS_GLOBAL && (source = name);
- for (key in source) (own = !IS_FORCED && target && void 0 !== target[key]) && key in exports || (out = own ? target[key] : source[key],
- exports[key] = IS_GLOBAL && "function" != typeof target[key] ? source[key] : IS_BIND && own ? ctx(out, global) : IS_WRAP && target[key] == out ? function(C) {
- var F = function(a, b, c) {
- if (this instanceof C) {
- switch (arguments.length) {
- case 0:
- return new C();
-
- case 1:
- return new C(a);
-
- case 2:
- return new C(a, b);
- }
- return new C(a, b, c);
- }
- return C.apply(this, arguments);
- };
- return F.prototype = C.prototype, F;
- }(out) : IS_PROTO && "function" == typeof out ? ctx(Function.call, out) : out, IS_PROTO && ((exports.virtual || (exports.virtual = {}))[key] = out,
- type & $export.R && expProto && !expProto[key] && hide(expProto, key, out)));
- };
- $export.F = 1, $export.G = 2, $export.S = 4, $export.P = 8, $export.B = 16, $export.W = 32,
- $export.U = 64, $export.R = 128, module.exports = $export;
-}, function(module, exports) {
- function isNil(value) {
- return null == value;
- }
- module.exports = isNil;
-}, function(module, exports, __webpack_require__) {
- var store = __webpack_require__(139)("wks"), uid = __webpack_require__(99), Symbol = __webpack_require__(24).Symbol, USE_SYMBOL = "function" == typeof Symbol;
- (module.exports = function(name) {
- return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)("Symbol." + name));
- }).store = store;
-}, function(module, exports, __webpack_require__) {
- var anObject = __webpack_require__(47), IE8_DOM_DEFINE = __webpack_require__(206), toPrimitive = __webpack_require__(133), dP = Object.defineProperty;
- exports.f = __webpack_require__(25) ? Object.defineProperty : function(O, P, Attributes) {
- if (anObject(O), P = toPrimitive(P, !0), anObject(Attributes), IE8_DOM_DEFINE) try {
- return dP(O, P, Attributes);
- } catch (e) {}
- if ("get" in Attributes || "set" in Attributes) throw TypeError("Accessors not supported!");
- return "value" in Attributes && (O[P] = Attributes.value), O;
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _defineProperty(obj, key, value) {
- return key in obj ? Object.defineProperty(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }) : obj[key] = value, obj;
- }
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return RADIAN;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return polarToCartesian;
- }), __webpack_require__.d(__webpack_exports__, "c", function() {
- return getMaxRadius;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return formatAxisMap;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return inRangeOfSector;
- });
- var __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_2__ChartUtils__ = __webpack_require__(16), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, RADIAN = Math.PI / 180, radianToDegree = function(angleInRadian) {
- return 180 * angleInRadian / Math.PI;
- }, polarToCartesian = function(cx, cy, radius, angle) {
- return {
- x: cx + Math.cos(-RADIAN * angle) * radius,
- y: cy + Math.sin(-RADIAN * angle) * radius
- };
- }, getMaxRadius = function(width, height) {
- var offset = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {
- top: 0,
- right: 0,
- bottom: 0,
- left: 0
- };
- return Math.min(Math.abs(width - (offset.left || 0) - (offset.right || 0)), Math.abs(height - (offset.top || 0) - (offset.bottom || 0))) / 2;
- }, formatAxisMap = function(props, axisMap, offset, axisType, chartName) {
- var width = props.width, height = props.height, startAngle = props.startAngle, endAngle = props.endAngle, cx = Object(__WEBPACK_IMPORTED_MODULE_1__DataUtils__.d)(props.cx, width, width / 2), cy = Object(__WEBPACK_IMPORTED_MODULE_1__DataUtils__.d)(props.cy, height, height / 2), maxRadius = getMaxRadius(width, height, offset), innerRadius = Object(__WEBPACK_IMPORTED_MODULE_1__DataUtils__.d)(props.innerRadius, maxRadius, 0), outerRadius = Object(__WEBPACK_IMPORTED_MODULE_1__DataUtils__.d)(props.outerRadius, maxRadius, .8 * maxRadius);
- return Object.keys(axisMap).reduce(function(result, id) {
- var axis = axisMap[id], domain = axis.domain, reversed = axis.reversed, range = void 0;
- __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(axis.range) ? ("angleAxis" === axisType ? range = [ startAngle, endAngle ] : "radiusAxis" === axisType && (range = [ innerRadius, outerRadius ]),
- reversed && (range = [ range[1], range[0] ])) : (range = axis.range, startAngle = range[0],
- endAngle = range[1]);
- var _parseScale = Object(__WEBPACK_IMPORTED_MODULE_2__ChartUtils__.A)(axis, chartName), realScaleType = _parseScale.realScaleType, scale = _parseScale.scale;
- scale.domain(domain).range(range), Object(__WEBPACK_IMPORTED_MODULE_2__ChartUtils__.c)(scale);
- var ticks = Object(__WEBPACK_IMPORTED_MODULE_2__ChartUtils__.v)(scale, _extends({}, axis, {
- realScaleType: realScaleType
- })), finalAxis = _extends({}, axis, ticks, {
- range: range,
- radius: outerRadius,
- realScaleType: realScaleType,
- scale: scale,
- cx: cx,
- cy: cy,
- innerRadius: innerRadius,
- outerRadius: outerRadius,
- startAngle: startAngle,
- endAngle: endAngle
- });
- return _extends({}, result, _defineProperty({}, id, finalAxis));
- }, {});
- }, distanceBetweenPoints = function(point, anotherPoint) {
- var x1 = point.x, y1 = point.y, x2 = anotherPoint.x, y2 = anotherPoint.y;
- return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
- }, getAngleOfPoint = function(_ref, _ref2) {
- var x = _ref.x, y = _ref.y, cx = _ref2.cx, cy = _ref2.cy, radius = distanceBetweenPoints({
- x: x,
- y: y
- }, {
- x: cx,
- y: cy
- });
- if (radius <= 0) return {
- radius: radius
- };
- var cos = (x - cx) / radius, angleInRadian = Math.acos(cos);
- return y > cy && (angleInRadian = 2 * Math.PI - angleInRadian), {
- radius: radius,
- angle: radianToDegree(angleInRadian),
- angleInRadian: angleInRadian
- };
- }, formatAngleOfSector = function(_ref3) {
- var startAngle = _ref3.startAngle, endAngle = _ref3.endAngle, startCnt = Math.floor(startAngle / 360), endCnt = Math.floor(endAngle / 360), min = Math.min(startCnt, endCnt);
- return {
- startAngle: startAngle - 360 * min,
- endAngle: endAngle - 360 * min
- };
- }, reverseFormatAngleOfSetor = function(angle, _ref4) {
- var startAngle = _ref4.startAngle, endAngle = _ref4.endAngle, startCnt = Math.floor(startAngle / 360), endCnt = Math.floor(endAngle / 360);
- return angle + 360 * Math.min(startCnt, endCnt);
- }, inRangeOfSector = function(_ref5, sector) {
- var x = _ref5.x, y = _ref5.y, _getAngleOfPoint = getAngleOfPoint({
- x: x,
- y: y
- }, sector), radius = _getAngleOfPoint.radius, angle = _getAngleOfPoint.angle, innerRadius = sector.innerRadius, outerRadius = sector.outerRadius;
- if (radius < innerRadius || radius > outerRadius) return !1;
- if (0 === radius) return !0;
- var _formatAngleOfSector = formatAngleOfSector(sector), startAngle = _formatAngleOfSector.startAngle, endAngle = _formatAngleOfSector.endAngle, formatAngle = angle, inRange = void 0;
- if (startAngle <= endAngle) {
- for (;formatAngle > endAngle; ) formatAngle -= 360;
- for (;formatAngle < startAngle; ) formatAngle += 360;
- inRange = formatAngle >= startAngle && formatAngle <= endAngle;
- } else {
- for (;formatAngle > startAngle; ) formatAngle -= 360;
- for (;formatAngle < endAngle; ) formatAngle += 360;
- inRange = formatAngle >= endAngle && formatAngle <= startAngle;
- }
- return inRange ? _extends({}, sector, {
- radius: radius,
- angle: reverseFormatAngleOfSetor(formatAngle, sector)
- }) : null;
- };
-}, function(module, exports) {
- var global = module.exports = "undefined" != typeof window && window.Math == Math ? window : "undefined" != typeof self && self.Math == Math ? self : Function("return this")();
- "number" == typeof __g && (__g = global);
-}, function(module, exports, __webpack_require__) {
- module.exports = !__webpack_require__(48)(function() {
- return 7 != Object.defineProperty({}, "a", {
- get: function() {
- return 7;
- }
- }).a;
- });
-}, function(module, exports, __webpack_require__) {
- module.exports = {
- default: __webpack_require__(355),
- __esModule: !0
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0, exports.default = function(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0;
- var _defineProperty = __webpack_require__(142), _defineProperty2 = function(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }(_defineProperty);
- exports.default = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), (0, _defineProperty2.default)(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }();
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0;
- var _typeof2 = __webpack_require__(101), _typeof3 = function(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }(_typeof2);
- exports.default = function(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" !== (void 0 === call ? "undefined" : (0, _typeof3.default)(call)) && "function" != typeof call ? self : call;
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- exports.__esModule = !0;
- var _setPrototypeOf = __webpack_require__(372), _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf), _create = __webpack_require__(376), _create2 = _interopRequireDefault(_create), _typeof2 = __webpack_require__(101), _typeof3 = _interopRequireDefault(_typeof2);
- exports.default = function(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + (void 0 === superClass ? "undefined" : (0,
- _typeof3.default)(superClass)));
- subClass.prototype = (0, _create2.default)(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (_setPrototypeOf2.default ? (0, _setPrototypeOf2.default)(subClass, superClass) : subClass.__proto__ = superClass);
- };
-}, function(module, exports) {
- function isObject(value) {
- var type = typeof value;
- return null != value && ("object" == type || "function" == type);
- }
- module.exports = isObject;
-}, function(module, exports, __webpack_require__) {
- var freeGlobal = __webpack_require__(243), freeSelf = "object" == typeof self && self && self.Object === Object && self, root = freeGlobal || freeSelf || Function("return this")();
- module.exports = root;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- }), exports.translateStyle = exports.AnimateGroup = exports.configBezier = exports.configSpring = void 0;
- var _Animate = __webpack_require__(264), _Animate2 = _interopRequireDefault(_Animate), _easing = __webpack_require__(277), _util = __webpack_require__(122), _AnimateGroup = __webpack_require__(681), _AnimateGroup2 = _interopRequireDefault(_AnimateGroup);
- exports.configSpring = _easing.configSpring, exports.configBezier = _easing.configBezier,
- exports.AnimateGroup = _AnimateGroup2.default, exports.translateStyle = _util.translateStyle,
- exports.default = _Animate2.default;
-}, function(module, exports, __webpack_require__) {
- function isEqual(value, other) {
- return baseIsEqual(value, other);
- }
- var baseIsEqual = __webpack_require__(177);
- module.exports = isEqual;
-}, function(module, exports) {
- module.exports = function(it) {
- return "object" == typeof it ? null !== it : "function" == typeof it;
- };
-}, function(module, exports) {
- function isObjectLike(value) {
- return null != value && "object" == typeof value;
- }
- module.exports = isObjectLike;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- var __WEBPACK_IMPORTED_MODULE_0__src_bisect__ = __webpack_require__(293);
- __webpack_require__.d(__webpack_exports__, "b", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_bisect__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_1__src_ascending__ = __webpack_require__(64);
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return __WEBPACK_IMPORTED_MODULE_1__src_ascending__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_2__src_bisector__ = __webpack_require__(294);
- __webpack_require__.d(__webpack_exports__, "c", function() {
- return __WEBPACK_IMPORTED_MODULE_2__src_bisector__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_18__src_quantile__ = (__webpack_require__(707), __webpack_require__(708),
- __webpack_require__(296), __webpack_require__(298), __webpack_require__(709), __webpack_require__(712),
- __webpack_require__(713), __webpack_require__(302), __webpack_require__(714), __webpack_require__(715),
- __webpack_require__(716), __webpack_require__(717), __webpack_require__(303), __webpack_require__(295),
- __webpack_require__(718), __webpack_require__(184));
- __webpack_require__.d(__webpack_exports__, "d", function() {
- return __WEBPACK_IMPORTED_MODULE_18__src_quantile__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_19__src_range__ = __webpack_require__(300);
- __webpack_require__.d(__webpack_exports__, "e", function() {
- return __WEBPACK_IMPORTED_MODULE_19__src_range__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_23__src_ticks__ = (__webpack_require__(719), __webpack_require__(720),
- __webpack_require__(721), __webpack_require__(301));
- __webpack_require__.d(__webpack_exports__, "h", function() {
- return __WEBPACK_IMPORTED_MODULE_23__src_ticks__.a;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return __WEBPACK_IMPORTED_MODULE_23__src_ticks__.b;
- }), __webpack_require__.d(__webpack_exports__, "g", function() {
- return __WEBPACK_IMPORTED_MODULE_23__src_ticks__.c;
- });
- __webpack_require__(304), __webpack_require__(297), __webpack_require__(722);
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_require__.d(__webpack_exports__, "d", function() {
- return durationSecond;
- }), __webpack_require__.d(__webpack_exports__, "c", function() {
- return durationMinute;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return durationHour;
- }), __webpack_require__.d(__webpack_exports__, "a", function() {
- return durationDay;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return durationWeek;
- });
- var durationSecond = 1e3, durationMinute = 6e4, durationHour = 36e5, durationDay = 864e5, durationWeek = 6048e5;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function makeEmptyFunction(arg) {
- return function() {
- return arg;
- };
- }
- var emptyFunction = function() {};
- emptyFunction.thatReturns = makeEmptyFunction, emptyFunction.thatReturnsFalse = makeEmptyFunction(!1),
- emptyFunction.thatReturnsTrue = makeEmptyFunction(!0), emptyFunction.thatReturnsNull = makeEmptyFunction(null),
- emptyFunction.thatReturnsThis = function() {
- return this;
- }, emptyFunction.thatReturnsArgument = function(arg) {
- return arg;
- }, module.exports = emptyFunction;
-}, function(module, exports, __webpack_require__) {
- var dP = __webpack_require__(22), createDesc = __webpack_require__(71);
- module.exports = __webpack_require__(25) ? function(object, key, value) {
- return dP.f(object, key, createDesc(1, value));
- } : function(object, key, value) {
- return object[key] = value, object;
- };
-}, function(module, exports, __webpack_require__) {
- function baseGetTag(value) {
- return null == value ? void 0 === value ? undefinedTag : nullTag : symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
- }
- var Symbol = __webpack_require__(78), getRawTag = __webpack_require__(522), objectToString = __webpack_require__(523), nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag = Symbol ? Symbol.toStringTag : void 0;
- module.exports = baseGetTag;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _toConsumableArray(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- return Array.from(arr);
- }
- function Label(props) {
- var viewBox = props.viewBox, position = props.position, value = props.value, children = props.children, content = props.content, _props$className = props.className, className = void 0 === _props$className ? "" : _props$className;
- if (!viewBox || __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(value) && __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(children) && !Object(__WEBPACK_IMPORTED_MODULE_3_react__.isValidElement)(content) && !__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(content)) return null;
- if (Object(__WEBPACK_IMPORTED_MODULE_3_react__.isValidElement)(content)) return Object(__WEBPACK_IMPORTED_MODULE_3_react__.cloneElement)(content, props);
- var label = void 0;
- if (__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(content)) {
- if (label = content(props), Object(__WEBPACK_IMPORTED_MODULE_3_react__.isValidElement)(label)) return label;
- } else label = getLabel(props);
- var isPolarLabel = isPolar(viewBox), attrs = Object(__WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__.k)(props);
- if (isPolarLabel && ("insideStart" === position || "insideEnd" === position || "end" === position)) return renderRadialLabel(props, label, attrs);
- var positionAttrs = isPolarLabel ? getAttrsOfPolarLabel(props) : getAttrsOfCartesianLabel(props);
- return __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_6__Text__.a, _extends({
- className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()("recharts-label", className)
- }, attrs, positionAttrs), label);
- }
- var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_3_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_react__), __WEBPACK_IMPORTED_MODULE_4_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_4_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_prop_types__), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__Text__ = __webpack_require__(54), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__ = __webpack_require__(23), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, cartesianViewBoxShape = __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.shape({
- x: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- y: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- width: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number
- }), polarViewBoxShape = __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.shape({
- cx: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- cy: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- innerRadius: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- outerRadius: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- startAngle: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- endAngle: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number
- }), propTypes = {
- viewBox: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.oneOfType([ cartesianViewBoxShape, polarViewBoxShape ]),
- formatter: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.func,
- value: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.string ]),
- offset: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.number,
- position: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.oneOf([ "top", "left", "right", "bottom", "inside", "outside", "insideLeft", "insideRight", "insideTop", "insideBottom", "insideTopLeft", "insideBottomLeft", "insideTopRight", "insideBottomRight", "insideStart", "insideEnd", "end", "center" ]),
- children: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.node), __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.node ]),
- className: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.string,
- content: __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.element, __WEBPACK_IMPORTED_MODULE_4_prop_types___default.a.func ])
- }, defaultProps = {
- offset: 5
- }, getLabel = function(props) {
- var value = props.value, formatter = props.formatter, label = __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(props.children) ? value : props.children;
- return __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(formatter) ? formatter(label) : label;
- }, getDeltaAngle = function(startAngle, endAngle) {
- return Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.j)(endAngle - startAngle) * Math.min(Math.abs(endAngle - startAngle), 360);
- }, renderRadialLabel = function(labelProps, label, attrs) {
- var position = labelProps.position, viewBox = labelProps.viewBox, offset = labelProps.offset, className = labelProps.className, cx = viewBox.cx, cy = viewBox.cy, innerRadius = viewBox.innerRadius, outerRadius = viewBox.outerRadius, startAngle = viewBox.startAngle, endAngle = viewBox.endAngle, clockWise = viewBox.clockWise, radius = (innerRadius + outerRadius) / 2, deltaAngle = getDeltaAngle(startAngle, endAngle), sign = deltaAngle >= 0 ? 1 : -1, labelAngle = void 0, direction = void 0;
- "insideStart" === position ? (labelAngle = startAngle + sign * offset, direction = clockWise) : "insideEnd" === position ? (labelAngle = endAngle - sign * offset,
- direction = !clockWise) : "end" === position && (labelAngle = endAngle + sign * offset,
- direction = clockWise), direction = deltaAngle <= 0 ? direction : !direction;
- var startPoint = Object(__WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__.e)(cx, cy, radius, labelAngle), endPoint = Object(__WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__.e)(cx, cy, radius, labelAngle + 359 * (direction ? 1 : -1)), path = "M" + startPoint.x + "," + startPoint.y + "\n A" + radius + "," + radius + ",0,1," + (direction ? 0 : 1) + ",\n " + endPoint.x + "," + endPoint.y, id = __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(labelProps.id) ? Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.k)("recharts-radial-line-") : labelProps.id;
- return __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement("text", _extends({}, attrs, {
- dominantBaseline: "central",
- className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()("recharts-radial-bar-label", className)
- }), __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement("defs", null, __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement("path", {
- id: id,
- d: path
- })), __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement("textPath", {
- xlinkHref: "#" + id
- }, label));
- }, getAttrsOfPolarLabel = function(props) {
- var viewBox = props.viewBox, offset = props.offset, position = props.position, cx = viewBox.cx, cy = viewBox.cy, innerRadius = viewBox.innerRadius, outerRadius = viewBox.outerRadius, startAngle = viewBox.startAngle, endAngle = viewBox.endAngle, midAngle = (startAngle + endAngle) / 2;
- if ("outside" === position) {
- var _polarToCartesian = Object(__WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__.e)(cx, cy, outerRadius + offset, midAngle), _x = _polarToCartesian.x;
- return {
- x: _x,
- y: _polarToCartesian.y,
- textAnchor: _x >= cx ? "start" : "end",
- verticalAnchor: "middle"
- };
- }
- if ("center" === position) return {
- x: cx,
- y: cy,
- textAnchor: "middle",
- verticalAnchor: "middle"
- };
- var r = (innerRadius + outerRadius) / 2, _polarToCartesian2 = Object(__WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__.e)(cx, cy, r, midAngle);
- return {
- x: _polarToCartesian2.x,
- y: _polarToCartesian2.y,
- textAnchor: "middle",
- verticalAnchor: "middle"
- };
- }, getAttrsOfCartesianLabel = function(props) {
- var viewBox = props.viewBox, offset = props.offset, position = props.position, x = viewBox.x, y = viewBox.y, width = viewBox.width, height = viewBox.height, sign = height >= 0 ? 1 : -1;
- return "top" === position ? {
- x: x + width / 2,
- y: y - sign * offset,
- textAnchor: "middle",
- verticalAnchor: "end"
- } : "bottom" === position ? {
- x: x + width / 2,
- y: y + height + sign * offset,
- textAnchor: "middle",
- verticalAnchor: "start"
- } : "left" === position ? {
- x: x - offset,
- y: y + height / 2,
- textAnchor: "end",
- verticalAnchor: "middle"
- } : "right" === position ? {
- x: x + width + offset,
- y: y + height / 2,
- textAnchor: "start",
- verticalAnchor: "middle"
- } : "insideLeft" === position ? {
- x: x + offset,
- y: y + height / 2,
- textAnchor: "start",
- verticalAnchor: "middle"
- } : "insideRight" === position ? {
- x: x + width - offset,
- y: y + height / 2,
- textAnchor: "end",
- verticalAnchor: "middle"
- } : "insideTop" === position ? {
- x: x + width / 2,
- y: y + sign * offset,
- textAnchor: "middle",
- verticalAnchor: "start"
- } : "insideBottom" === position ? {
- x: x + width / 2,
- y: y + height - sign * offset,
- textAnchor: "middle",
- verticalAnchor: "end"
- } : "insideTopLeft" === position ? {
- x: x + offset,
- y: y + sign * offset,
- textAnchor: "start",
- verticalAnchor: "start"
- } : "insideTopRight" === position ? {
- x: x + width - offset,
- y: y + sign * offset,
- textAnchor: "end",
- verticalAnchor: "start"
- } : "insideBottomLeft" === position ? {
- x: x + offset,
- y: y + height - sign * offset,
- textAnchor: "start",
- verticalAnchor: "end"
- } : "insideBottomRight" === position ? {
- x: x + width - offset,
- y: y + height - sign * offset,
- textAnchor: "end",
- verticalAnchor: "end"
- } : __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default()(position) && (Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(position.x) || Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.i)(position.x)) && (Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(position.y) || Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.i)(position.y)) ? {
- x: x + Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.d)(position.x, width),
- y: y + Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.d)(position.y, height),
- textAnchor: "end",
- verticalAnchor: "end"
- } : {
- x: x + width / 2,
- y: y + height / 2,
- textAnchor: "middle",
- verticalAnchor: "middle"
- };
- }, isPolar = function(viewBox) {
- return Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(viewBox.cx);
- };
- Label.displayName = "Label", Label.defaultProps = defaultProps, Label.propTypes = propTypes;
- var parseViewBox = function(props) {
- var cx = props.cx, cy = props.cy, angle = props.angle, startAngle = props.startAngle, endAngle = props.endAngle, r = props.r, radius = props.radius, innerRadius = props.innerRadius, outerRadius = props.outerRadius, x = props.x, y = props.y, top = props.top, left = props.left, width = props.width, height = props.height, clockWise = props.clockWise;
- if (Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(width) && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(height)) {
- if (Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(x) && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(y)) return {
- x: x,
- y: y,
- width: width,
- height: height
- };
- if (Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(top) && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(left)) return {
- x: top,
- y: left,
- width: width,
- height: height
- };
- }
- return Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(x) && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(y) ? {
- x: x,
- y: y,
- width: 0,
- height: 0
- } : Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(cx) && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(cy) ? {
- cx: cx,
- cy: cy,
- startAngle: startAngle || angle || 0,
- endAngle: endAngle || angle || 0,
- innerRadius: innerRadius || 0,
- outerRadius: outerRadius || radius || r || 0,
- clockWise: clockWise
- } : props.viewBox ? props.viewBox : {};
- }, parseLabel = function(label, viewBox) {
- return label ? !0 === label ? __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement(Label, {
- key: "label-implicit",
- viewBox: viewBox
- }) : Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.g)(label) ? __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement(Label, {
- key: "label-implicit",
- viewBox: viewBox,
- value: label
- }) : Object(__WEBPACK_IMPORTED_MODULE_3_react__.isValidElement)(label) || __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(label) ? __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement(Label, {
- key: "label-implicit",
- content: label,
- viewBox: viewBox
- }) : __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default()(label) ? __WEBPACK_IMPORTED_MODULE_3_react___default.a.createElement(Label, _extends({
- viewBox: viewBox
- }, label, {
- key: "label-implicit"
- })) : null : null;
- }, renderCallByParent = function(parentProps, viewBox) {
- var ckeckPropsLabel = !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2];
- if (!parentProps || !parentProps.children && ckeckPropsLabel && !parentProps.label) return null;
- var children = parentProps.children, parentViewBox = parseViewBox(parentProps), explicitChilren = Object(__WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__.h)(children, Label).map(function(child, index) {
- return Object(__WEBPACK_IMPORTED_MODULE_3_react__.cloneElement)(child, {
- viewBox: viewBox || parentViewBox,
- key: "label-" + index
- });
- });
- return ckeckPropsLabel ? [ parseLabel(parentProps.label, viewBox || parentViewBox) ].concat(_toConsumableArray(explicitChilren)) : explicitChilren;
- };
- Label.parseViewBox = parseViewBox, Label.renderCallByParent = renderCallByParent,
- __webpack_exports__.a = Label;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- var __WEBPACK_IMPORTED_MODULE_0__src_color__ = __webpack_require__(187);
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_color__.e;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_color__.g;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_color__.f;
- });
- var __WEBPACK_IMPORTED_MODULE_1__src_lab__ = __webpack_require__(730);
- __webpack_require__.d(__webpack_exports__, "e", function() {
- return __WEBPACK_IMPORTED_MODULE_1__src_lab__.a;
- }), __webpack_require__.d(__webpack_exports__, "c", function() {
- return __WEBPACK_IMPORTED_MODULE_1__src_lab__.b;
- });
- var __WEBPACK_IMPORTED_MODULE_2__src_cubehelix__ = __webpack_require__(731);
- __webpack_require__.d(__webpack_exports__, "b", function() {
- return __WEBPACK_IMPORTED_MODULE_2__src_cubehelix__.a;
- });
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _toConsumableArray(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- return Array.from(arr);
- }
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function LabelList(props) {
- var data = props.data, valueAccessor = props.valueAccessor, dataKey = props.dataKey, clockWise = props.clockWise, id = props.id, others = _objectWithoutProperties(props, [ "data", "valueAccessor", "dataKey", "clockWise", "id" ]);
- return data && data.length ? __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_8__container_Layer__.a, {
- className: "recharts-label-list"
- }, data.map(function(entry, index) {
- var value = __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(dataKey) ? valueAccessor(entry, index) : Object(__WEBPACK_IMPORTED_MODULE_10__util_ChartUtils__.w)(entry && entry.payload, dataKey), idProps = __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(id) ? {} : {
- id: id + "-" + index
- };
- return __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_7__Label__.a, _extends({}, Object(__WEBPACK_IMPORTED_MODULE_9__util_ReactUtils__.k)(entry), others, idProps, {
- index: index,
- value: value,
- viewBox: __WEBPACK_IMPORTED_MODULE_7__Label__.a.parseViewBox(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default()(clockWise) ? entry : _extends({}, entry, {
- clockWise: clockWise
- })),
- key: "label-" + index
- }));
- })) : null;
- }
- var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_lodash_last__ = __webpack_require__(781), __WEBPACK_IMPORTED_MODULE_3_lodash_last___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_last__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__Label__ = __webpack_require__(42), __WEBPACK_IMPORTED_MODULE_8__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_9__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_10__util_ChartUtils__ = __webpack_require__(16), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, propTypes = {
- id: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- data: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.object),
- valueAccessor: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- clockWise: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.bool,
- dataKey: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func ])
- }, defaultProps = {
- valueAccessor: function(entry) {
- return __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default()(entry.value) ? __WEBPACK_IMPORTED_MODULE_3_lodash_last___default()(entry.value) : entry.value;
- }
- };
- LabelList.propTypes = propTypes, LabelList.displayName = "LabelList";
- var parseLabelList = function(label, data) {
- return label ? !0 === label ? __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(LabelList, {
- key: "labelList-implicit",
- data: data
- }) : __WEBPACK_IMPORTED_MODULE_5_react___default.a.isValidElement(label) || __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(label) ? __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(LabelList, {
- key: "labelList-implicit",
- data: data,
- content: label
- }) : __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default()(label) ? __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(LabelList, _extends({
- data: data
- }, label, {
- key: "labelList-implicit"
- })) : null : null;
- }, renderCallByParent = function(parentProps, data) {
- var ckeckPropsLabel = !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2];
- if (!parentProps || !parentProps.children && ckeckPropsLabel && !parentProps.label) return null;
- var children = parentProps.children, explicitChilren = Object(__WEBPACK_IMPORTED_MODULE_9__util_ReactUtils__.h)(children, LabelList).map(function(child, index) {
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(child, {
- data: data,
- key: "labelList-" + index
- });
- });
- return ckeckPropsLabel ? [ parseLabelList(parentProps.label, data) ].concat(_toConsumableArray(explicitChilren)) : explicitChilren;
- };
- LabelList.renderCallByParent = renderCallByParent, LabelList.defaultProps = defaultProps,
- __webpack_exports__.a = LabelList;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function _defineProperty(obj, key, value) {
- return key in obj ? Object.defineProperty(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }) : obj[key] = value, obj;
- }
- function _toConsumableArray(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- return Array.from(arr);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__ = __webpack_require__(284), __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_range__ = __webpack_require__(334), __WEBPACK_IMPORTED_MODULE_2_lodash_range___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_range__), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle__ = __webpack_require__(790), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_throttle__), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_7_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_classnames__), __WEBPACK_IMPORTED_MODULE_8__container_Surface__ = __webpack_require__(79), __WEBPACK_IMPORTED_MODULE_9__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__ = __webpack_require__(121), __WEBPACK_IMPORTED_MODULE_11__component_Legend__ = __webpack_require__(170), __WEBPACK_IMPORTED_MODULE_12__shape_Curve__ = __webpack_require__(66), __WEBPACK_IMPORTED_MODULE_13__shape_Cross__ = __webpack_require__(328), __WEBPACK_IMPORTED_MODULE_14__shape_Sector__ = __webpack_require__(127), __WEBPACK_IMPORTED_MODULE_15__shape_Dot__ = __webpack_require__(56), __WEBPACK_IMPORTED_MODULE_16__shape_Rectangle__ = __webpack_require__(65), __WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__ = __webpack_require__(335), __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__ = __webpack_require__(333), __WEBPACK_IMPORTED_MODULE_20__util_DOMUtils__ = __webpack_require__(183), __WEBPACK_IMPORTED_MODULE_21__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__ = __webpack_require__(16), __WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__ = __webpack_require__(23), __WEBPACK_IMPORTED_MODULE_24__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_25__util_Events__ = __webpack_require__(791), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), ORIENT_MAP = {
- xAxis: [ "bottom", "top" ],
- yAxis: [ "left", "right" ]
- }, originCoordinate = {
- x: 0,
- y: 0
- }, generateCategoricalChart = function(_ref) {
- var _class, _temp, _initialiseProps, chartName = _ref.chartName, GraphicalChild = _ref.GraphicalChild, _ref$eventType = _ref.eventType, eventType = void 0 === _ref$eventType ? "axis" : _ref$eventType, axisComponents = _ref.axisComponents, legendContent = _ref.legendContent, formatAxisMap = _ref.formatAxisMap, defaultProps = _ref.defaultProps, propTypes = _ref.propTypes;
- return _temp = _class = function(_Component) {
- function CategoricalChartWrapper(props) {
- _classCallCheck(this, CategoricalChartWrapper);
- var _this = _possibleConstructorReturn(this, (CategoricalChartWrapper.__proto__ || Object.getPrototypeOf(CategoricalChartWrapper)).call(this, props));
- _initialiseProps.call(_this);
- var defaultState = _this.constructor.createDefaultState(props);
- return _this.state = _extends({}, defaultState, {
- updateId: 0
- }, _this.updateStateOfAxisMapsOffsetAndStackGroups(_extends({
- props: props
- }, defaultState, {
- updateId: 0
- }))), _this.uniqueChartId = __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(props.id) ? Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.k)("recharts") : props.id,
- props.throttleDelay && (_this.triggeredAfterMouseMove = __WEBPACK_IMPORTED_MODULE_3_lodash_throttle___default()(_this.triggeredAfterMouseMove, props.throttleDelay)),
- _this;
- }
- return _inherits(CategoricalChartWrapper, _Component), _createClass(CategoricalChartWrapper, [ {
- key: "componentDidMount",
- value: function() {
- __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(this.props.syncId) || this.addListener();
- }
- }, {
- key: "componentWillReceiveProps",
- value: function(nextProps) {
- var _props = this.props, data = _props.data, children = _props.children, width = _props.width, height = _props.height, layout = _props.layout, stackOffset = _props.stackOffset, margin = _props.margin, updateId = this.state.updateId;
- if (nextProps.data === data && nextProps.width === width && nextProps.height === height && nextProps.layout === layout && nextProps.stackOffset === stackOffset && Object(__WEBPACK_IMPORTED_MODULE_24__util_PureRender__.b)(nextProps.margin, margin)) {
- if (!Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.m)(nextProps.children, children)) {
- var hasGlobalData = !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(nextProps.data), newUpdateId = hasGlobalData ? updateId : updateId + 1, _state = this.state, dataStartIndex = _state.dataStartIndex, dataEndIndex = _state.dataEndIndex, _defaultState = _extends({}, this.constructor.createDefaultState(nextProps), {
- dataEndIndex: dataEndIndex,
- dataStartIndex: dataStartIndex
- });
- this.setState(_extends({}, _defaultState, {
- updateId: newUpdateId
- }, this.updateStateOfAxisMapsOffsetAndStackGroups(_extends({
- props: nextProps
- }, _defaultState, {
- updateId: newUpdateId
- }))));
- }
- } else {
- var defaultState = this.constructor.createDefaultState(nextProps);
- this.setState(_extends({}, defaultState, {
- updateId: updateId + 1
- }, this.updateStateOfAxisMapsOffsetAndStackGroups(_extends({
- props: nextProps
- }, defaultState, {
- updateId: updateId + 1
- }))));
- }
- __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(this.props.syncId) && !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(nextProps.syncId) && this.addListener(),
- !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(this.props.syncId) && __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(nextProps.syncId) && this.removeListener();
- }
- }, {
- key: "componentWillUnmount",
- value: function() {
- __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(this.props.syncId) || this.removeListener(),
- "function" == typeof this.triggeredAfterMouseMove.cancel && this.triggeredAfterMouseMove.cancel();
- }
- }, {
- key: "getAxisMap",
- value: function(props, _ref2) {
- var _ref2$axisType = _ref2.axisType, axisType = void 0 === _ref2$axisType ? "xAxis" : _ref2$axisType, AxisComp = _ref2.AxisComp, graphicalItems = _ref2.graphicalItems, stackGroups = _ref2.stackGroups, dataStartIndex = _ref2.dataStartIndex, dataEndIndex = _ref2.dataEndIndex, children = props.children, axisIdKey = axisType + "Id", axes = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.h)(children, AxisComp), axisMap = {};
- return axes && axes.length ? axisMap = this.getAxisMapByAxes(props, {
- axes: axes,
- graphicalItems: graphicalItems,
- axisType: axisType,
- axisIdKey: axisIdKey,
- stackGroups: stackGroups,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }) : graphicalItems && graphicalItems.length && (axisMap = this.getAxisMapByItems(props, {
- Axis: AxisComp,
- graphicalItems: graphicalItems,
- axisType: axisType,
- axisIdKey: axisIdKey,
- stackGroups: stackGroups,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- })), axisMap;
- }
- }, {
- key: "getAxisMapByAxes",
- value: function(props, _ref3) {
- var _this2 = this, axes = _ref3.axes, graphicalItems = _ref3.graphicalItems, axisType = _ref3.axisType, axisIdKey = _ref3.axisIdKey, stackGroups = _ref3.stackGroups, dataStartIndex = _ref3.dataStartIndex, dataEndIndex = _ref3.dataEndIndex, layout = props.layout, children = props.children, stackOffset = props.stackOffset, isCategorial = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.x)(layout, axisType);
- return axes.reduce(function(result, child) {
- var _child$props = child.props, type = _child$props.type, dataKey = _child$props.dataKey, allowDataOverflow = _child$props.allowDataOverflow, allowDuplicatedCategory = _child$props.allowDuplicatedCategory, scale = _child$props.scale, ticks = _child$props.ticks, axisId = child.props[axisIdKey], displayedData = _this2.constructor.getDisplayedData(props, {
- graphicalItems: graphicalItems.filter(function(item) {
- return item.props[axisIdKey] === axisId;
- }),
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }), len = displayedData.length;
- if (!result[axisId]) {
- var domain = void 0, duplicateDomain = void 0, categoricalDomain = void 0;
- if (dataKey) {
- if (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.n)(displayedData, dataKey, type),
- "category" === type && isCategorial) {
- var duplicate = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.e)(domain);
- allowDuplicatedCategory && duplicate ? (duplicateDomain = domain, domain = __WEBPACK_IMPORTED_MODULE_2_lodash_range___default()(0, len)) : allowDuplicatedCategory || (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.y)(child.props.domain, domain, child).reduce(function(finalDomain, entry) {
- return finalDomain.indexOf(entry) >= 0 ? finalDomain : [].concat(_toConsumableArray(finalDomain), [ entry ]);
- }, []));
- } else if ("category" === type) domain = allowDuplicatedCategory ? domain.filter(function(entry) {
- return "" !== entry && !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(entry);
- }) : Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.y)(child.props.domain, domain, child).reduce(function(finalDomain, entry) {
- return finalDomain.indexOf(entry) >= 0 || "" === entry || __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(entry) ? finalDomain : [].concat(_toConsumableArray(finalDomain), [ entry ]);
- }, []); else if ("number" === type) {
- var errorBarsDomain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.z)(displayedData, graphicalItems.filter(function(item) {
- return item.props[axisIdKey] === axisId && !item.props.hide;
- }), dataKey, axisType);
- errorBarsDomain && (domain = errorBarsDomain);
- }
- !isCategorial || "number" !== type && "auto" === scale || (categoricalDomain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.n)(displayedData, dataKey, "category"));
- } else domain = isCategorial ? __WEBPACK_IMPORTED_MODULE_2_lodash_range___default()(0, len) : stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack && "number" === type ? "expand" === stackOffset ? [ 0, 1 ] : Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.p)(stackGroups[axisId].stackGroups, dataStartIndex, dataEndIndex) : Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.o)(displayedData, graphicalItems.filter(function(item) {
- return item.props[axisIdKey] === axisId && !item.props.hide;
- }), type, !0);
- return "number" === type && (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.e)(children, domain, axisId, axisType, ticks),
- child.props.domain && (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.B)(child.props.domain, domain, allowDataOverflow))),
- _extends({}, result, _defineProperty({}, axisId, _extends({}, child.props, {
- axisType: axisType,
- domain: domain,
- categoricalDomain: categoricalDomain,
- duplicateDomain: duplicateDomain,
- originalDomain: child.props.domain,
- isCategorial: isCategorial,
- layout: layout
- })));
- }
- return result;
- }, {});
- }
- }, {
- key: "getAxisMapByItems",
- value: function(props, _ref4) {
- var graphicalItems = _ref4.graphicalItems, Axis = _ref4.Axis, axisType = _ref4.axisType, axisIdKey = _ref4.axisIdKey, stackGroups = _ref4.stackGroups, dataStartIndex = _ref4.dataStartIndex, dataEndIndex = _ref4.dataEndIndex, layout = props.layout, children = props.children, displayedData = this.constructor.getDisplayedData(props, {
- graphicalItems: graphicalItems,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }), len = displayedData.length, isCategorial = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.x)(layout, axisType), index = -1;
- return graphicalItems.reduce(function(result, child) {
- var axisId = child.props[axisIdKey];
- if (!result[axisId]) {
- index++;
- var domain = void 0;
- return isCategorial ? domain = __WEBPACK_IMPORTED_MODULE_2_lodash_range___default()(0, len) : stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack ? (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.p)(stackGroups[axisId].stackGroups, dataStartIndex, dataEndIndex),
- domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.e)(children, domain, axisId, axisType)) : (domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.B)(Axis.defaultProps.domain, Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.o)(displayedData, graphicalItems.filter(function(item) {
- return item.props[axisIdKey] === axisId && !item.props.hide;
- }), "number"), Axis.defaultProps.allowDataOverflow), domain = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.e)(children, domain, axisId, axisType)),
- _extends({}, result, _defineProperty({}, axisId, _extends({
- axisType: axisType
- }, Axis.defaultProps, {
- hide: !0,
- orientation: ORIENT_MAP[axisType] && ORIENT_MAP[axisType][index % 2],
- domain: domain,
- originalDomain: Axis.defaultProps.domain,
- isCategorial: isCategorial,
- layout: layout
- })));
- }
- return result;
- }, {});
- }
- }, {
- key: "getActiveCoordinate",
- value: function(tooltipTicks, activeIndex, rangeObj) {
- var layout = this.props.layout, entry = tooltipTicks.find(function(tick) {
- return tick && tick.index === activeIndex;
- });
- if (entry) {
- if ("horizontal" === layout) return {
- x: entry.coordinate,
- y: rangeObj.y
- };
- if ("vertical" === layout) return {
- x: rangeObj.x,
- y: entry.coordinate
- };
- if ("centric" === layout) {
- var _angle = entry.coordinate, _radius = rangeObj.radius;
- return _extends({}, rangeObj, Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(rangeObj.cx, rangeObj.cy, _radius, _angle), {
- angle: _angle,
- radius: _radius
- });
- }
- var radius = entry.coordinate, angle = rangeObj.angle;
- return _extends({}, rangeObj, Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(rangeObj.cx, rangeObj.cy, radius, angle), {
- angle: angle,
- radius: radius
- });
- }
- return originCoordinate;
- }
- }, {
- key: "getMouseInfo",
- value: function(event) {
- if (!this.container) return null;
- var containerOffset = Object(__WEBPACK_IMPORTED_MODULE_20__util_DOMUtils__.b)(this.container), e = Object(__WEBPACK_IMPORTED_MODULE_20__util_DOMUtils__.a)(event, containerOffset), rangeObj = this.inRange(e.chartX, e.chartY);
- if (!rangeObj) return null;
- var _state2 = this.state, xAxisMap = _state2.xAxisMap, yAxisMap = _state2.yAxisMap;
- if ("axis" !== eventType && xAxisMap && yAxisMap) {
- var xScale = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(xAxisMap).scale, yScale = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(yAxisMap).scale, xValue = xScale && xScale.invert ? xScale.invert(e.chartX) : null, yValue = yScale && yScale.invert ? yScale.invert(e.chartY) : null;
- return _extends({}, e, {
- xValue: xValue,
- yValue: yValue
- });
- }
- var _state3 = this.state, ticks = _state3.orderedTooltipTicks, axis = _state3.tooltipAxis, tooltipTicks = _state3.tooltipTicks, pos = this.calculateTooltipPos(rangeObj), activeIndex = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.b)(pos, ticks, tooltipTicks, axis);
- if (activeIndex >= 0 && tooltipTicks) {
- var activeLabel = tooltipTicks[activeIndex] && tooltipTicks[activeIndex].value, activePayload = this.getTooltipContent(activeIndex, activeLabel), activeCoordinate = this.getActiveCoordinate(ticks, activeIndex, rangeObj);
- return _extends({}, e, {
- activeTooltipIndex: activeIndex,
- activeLabel: activeLabel,
- activePayload: activePayload,
- activeCoordinate: activeCoordinate
- });
- }
- return null;
- }
- }, {
- key: "getTooltipContent",
- value: function(activeIndex, activeLabel) {
- var _state4 = this.state, graphicalItems = _state4.graphicalItems, tooltipAxis = _state4.tooltipAxis, displayedData = this.constructor.getDisplayedData(this.props, this.state);
- return activeIndex < 0 || !graphicalItems || !graphicalItems.length || activeIndex >= displayedData.length ? null : graphicalItems.reduce(function(result, child) {
- if (child.props.hide) return result;
- var _child$props2 = child.props, dataKey = _child$props2.dataKey, name = _child$props2.name, unit = _child$props2.unit, formatter = _child$props2.formatter, data = _child$props2.data, payload = void 0;
- return payload = tooltipAxis.dataKey && !tooltipAxis.allowDuplicatedCategory ? Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.a)(data || displayedData, tooltipAxis.dataKey, activeLabel) : displayedData[activeIndex],
- payload ? [].concat(_toConsumableArray(result), [ _extends({}, Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.k)(child), {
- dataKey: dataKey,
- unit: unit,
- formatter: formatter,
- name: name || dataKey,
- color: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.r)(child),
- value: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.w)(payload, dataKey),
- payload: payload
- }) ]) : result;
- }, []);
- }
- }, {
- key: "getFormatItems",
- value: function(props, currentState) {
- var _this3 = this, graphicalItems = currentState.graphicalItems, stackGroups = currentState.stackGroups, offset = currentState.offset, updateId = currentState.updateId, dataStartIndex = currentState.dataStartIndex, dataEndIndex = currentState.dataEndIndex, barSize = props.barSize, layout = props.layout, barGap = props.barGap, barCategoryGap = props.barCategoryGap, globalMaxBarSize = props.maxBarSize, _getAxisNameByLayout = this.getAxisNameByLayout(layout), numericAxisName = _getAxisNameByLayout.numericAxisName, cateAxisName = _getAxisNameByLayout.cateAxisName, hasBar = this.constructor.hasBar(graphicalItems), sizeList = hasBar && Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.i)({
- barSize: barSize,
- stackGroups: stackGroups
- }), formatedItems = [];
- return graphicalItems.forEach(function(item, index) {
- var displayedData = _this3.constructor.getDisplayedData(props, {
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }, item), _item$props = item.props, dataKey = _item$props.dataKey, childMaxBarSize = _item$props.maxBarSize, numericAxisId = item.props[numericAxisName + "Id"], cateAxisId = item.props[cateAxisName + "Id"], axisObj = axisComponents.reduce(function(result, entry) {
- var _extends4, axisMap = currentState[entry.axisType + "Map"], id = item.props[entry.axisType + "Id"], axis = axisMap && axisMap[id];
- return _extends({}, result, (_extends4 = {}, _defineProperty(_extends4, entry.axisType, axis),
- _defineProperty(_extends4, entry.axisType + "Ticks", Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(axis)),
- _extends4));
- }, {}), cateAxis = axisObj[cateAxisName], cateTicks = axisObj[cateAxisName + "Ticks"], stackedData = stackGroups && stackGroups[numericAxisId] && stackGroups[numericAxisId].hasStack && Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.t)(item, stackGroups[numericAxisId].stackGroups), bandSize = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.g)(cateAxis, cateTicks), maxBarSize = __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(childMaxBarSize) ? globalMaxBarSize : childMaxBarSize, barPosition = hasBar && Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.h)({
- barGap: barGap,
- barCategoryGap: barCategoryGap,
- bandSize: bandSize,
- sizeList: sizeList[cateAxisId],
- maxBarSize: maxBarSize
- }), componsedFn = item && item.type && item.type.getComposedData;
- if (componsedFn) {
- var _extends5;
- formatedItems.push({
- props: _extends({}, componsedFn(_extends({}, axisObj, {
- displayedData: displayedData,
- props: props,
- dataKey: dataKey,
- item: item,
- bandSize: bandSize,
- barPosition: barPosition,
- offset: offset,
- stackedData: stackedData,
- layout: layout,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex,
- onItemMouseLeave: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.d)(_this3.handleItemMouseLeave, null, item.props.onMouseLeave),
- onItemMouseEnter: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.d)(_this3.handleItemMouseEnter, null, item.props.onMouseEnter)
- })), (_extends5 = {
- key: item.key || "item-" + index
- }, _defineProperty(_extends5, numericAxisName, axisObj[numericAxisName]), _defineProperty(_extends5, cateAxisName, axisObj[cateAxisName]),
- _defineProperty(_extends5, "animationId", updateId), _extends5)),
- childIndex: Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.o)(item, props.children),
- item: item
- });
- }
- }), formatedItems;
- }
- }, {
- key: "getCursorRectangle",
- value: function() {
- var layout = this.props.layout, _state5 = this.state, activeCoordinate = _state5.activeCoordinate, offset = _state5.offset, tooltipAxisBandSize = _state5.tooltipAxisBandSize, halfSize = tooltipAxisBandSize / 2;
- return {
- stroke: "none",
- fill: "#ccc",
- x: "horizontal" === layout ? activeCoordinate.x - halfSize : offset.left + .5,
- y: "horizontal" === layout ? offset.top + .5 : activeCoordinate.y - halfSize,
- width: "horizontal" === layout ? tooltipAxisBandSize : offset.width - 1,
- height: "horizontal" === layout ? offset.height - 1 : tooltipAxisBandSize
- };
- }
- }, {
- key: "getCursorPoints",
- value: function() {
- var layout = this.props.layout, _state6 = this.state, activeCoordinate = _state6.activeCoordinate, offset = _state6.offset, x1 = void 0, y1 = void 0, x2 = void 0, y2 = void 0;
- if ("horizontal" === layout) x1 = activeCoordinate.x, x2 = x1, y1 = offset.top,
- y2 = offset.top + offset.height; else if ("vertical" === layout) y1 = activeCoordinate.y,
- y2 = y1, x1 = offset.left, x2 = offset.left + offset.width; else if (!__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(activeCoordinate.cx) || !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(activeCoordinate.cy)) {
- if ("centric" !== layout) {
- var _cx = activeCoordinate.cx, _cy = activeCoordinate.cy, radius = activeCoordinate.radius, startAngle = activeCoordinate.startAngle, endAngle = activeCoordinate.endAngle, startPoint = Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(_cx, _cy, radius, startAngle), endPoint = Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(_cx, _cy, radius, endAngle);
- return {
- points: [ startPoint, endPoint ],
- cx: _cx,
- cy: _cy,
- radius: radius,
- startAngle: startAngle,
- endAngle: endAngle
- };
- }
- var cx = activeCoordinate.cx, cy = activeCoordinate.cy, innerRadius = activeCoordinate.innerRadius, outerRadius = activeCoordinate.outerRadius, angle = activeCoordinate.angle, innerPoint = Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(cx, cy, innerRadius, angle), outerPoint = Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.e)(cx, cy, outerRadius, angle);
- x1 = innerPoint.x, y1 = innerPoint.y, x2 = outerPoint.x, y2 = outerPoint.y;
- }
- return [ {
- x: x1,
- y: y1
- }, {
- x: x2,
- y: y2
- } ];
- }
- }, {
- key: "getAxisNameByLayout",
- value: function(layout) {
- return "horizontal" === layout ? {
- numericAxisName: "yAxis",
- cateAxisName: "xAxis"
- } : "vertical" === layout ? {
- numericAxisName: "xAxis",
- cateAxisName: "yAxis"
- } : "centric" === layout ? {
- numericAxisName: "radiusAxis",
- cateAxisName: "angleAxis"
- } : {
- numericAxisName: "angleAxis",
- cateAxisName: "radiusAxis"
- };
- }
- }, {
- key: "calculateTooltipPos",
- value: function(rangeObj) {
- var layout = this.props.layout;
- return "horizontal" === layout ? rangeObj.x : "vertical" === layout ? rangeObj.y : "centric" === layout ? rangeObj.angle : rangeObj.radius;
- }
- }, {
- key: "inRange",
- value: function(x, y) {
- var layout = this.props.layout;
- if ("horizontal" === layout || "vertical" === layout) {
- var offset = this.state.offset;
- return x >= offset.left && x <= offset.left + offset.width && y >= offset.top && y <= offset.top + offset.height ? {
- x: x,
- y: y
- } : null;
- }
- var _state7 = this.state, angleAxisMap = _state7.angleAxisMap, radiusAxisMap = _state7.radiusAxisMap;
- if (angleAxisMap && radiusAxisMap) {
- var angleAxis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(angleAxisMap);
- return Object(__WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__.d)({
- x: x,
- y: y
- }, angleAxis);
- }
- return null;
- }
- }, {
- key: "parseEventsOfWrapper",
- value: function() {
- var children = this.props.children, tooltipItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__.a), tooltipEvents = tooltipItem && "axis" === eventType ? {
- onMouseEnter: this.handleMouseEnter,
- onMouseMove: this.handleMouseMove,
- onMouseLeave: this.handleMouseLeave,
- onTouchMove: this.handleTouchMove
- } : {}, outerEvents = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.e)(this.props, this.handleOuterEvent);
- return _extends({}, outerEvents, tooltipEvents);
- }
- }, {
- key: "updateStateOfAxisMapsOffsetAndStackGroups",
- value: function(_ref5) {
- var _this4 = this, props = _ref5.props, dataStartIndex = _ref5.dataStartIndex, dataEndIndex = _ref5.dataEndIndex, updateId = _ref5.updateId;
- if (!Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.q)({
- props: props
- })) return null;
- var children = props.children, layout = props.layout, stackOffset = props.stackOffset, data = props.data, reverseStackOrder = props.reverseStackOrder, _getAxisNameByLayout2 = this.getAxisNameByLayout(layout), numericAxisName = _getAxisNameByLayout2.numericAxisName, cateAxisName = _getAxisNameByLayout2.cateAxisName, graphicalItems = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.h)(children, GraphicalChild), stackGroups = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.s)(data, graphicalItems, numericAxisName + "Id", cateAxisName + "Id", stackOffset, reverseStackOrder), axisObj = axisComponents.reduce(function(result, entry) {
- var name = entry.axisType + "Map";
- return _extends({}, result, _defineProperty({}, name, _this4.getAxisMap(props, _extends({}, entry, {
- graphicalItems: graphicalItems,
- stackGroups: entry.axisType === numericAxisName && stackGroups,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }))));
- }, {}), offset = this.calculateOffset(_extends({}, axisObj, {
- props: props,
- graphicalItems: graphicalItems
- }));
- Object.keys(axisObj).forEach(function(key) {
- axisObj[key] = formatAxisMap(props, axisObj[key], offset, key.replace("Map", ""), chartName);
- });
- var cateAxisMap = axisObj[cateAxisName + "Map"], ticksObj = this.tooltipTicksGenerator(cateAxisMap), formatedGraphicalItems = this.getFormatItems(props, _extends({}, axisObj, {
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex,
- updateId: updateId,
- graphicalItems: graphicalItems,
- stackGroups: stackGroups,
- offset: offset
- }));
- return _extends({
- formatedGraphicalItems: formatedGraphicalItems,
- graphicalItems: graphicalItems,
- offset: offset,
- stackGroups: stackGroups
- }, ticksObj, axisObj);
- }
- }, {
- key: "addListener",
- value: function() {
- __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.on(__WEBPACK_IMPORTED_MODULE_25__util_Events__.a, this.handleReceiveSyncEvent),
- __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.setMaxListeners && __WEBPACK_IMPORTED_MODULE_25__util_Events__.b._maxListeners && __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.setMaxListeners(__WEBPACK_IMPORTED_MODULE_25__util_Events__.b._maxListeners + 1);
- }
- }, {
- key: "removeListener",
- value: function() {
- __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.removeListener(__WEBPACK_IMPORTED_MODULE_25__util_Events__.a, this.handleReceiveSyncEvent),
- __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.setMaxListeners && __WEBPACK_IMPORTED_MODULE_25__util_Events__.b._maxListeners && __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.setMaxListeners(__WEBPACK_IMPORTED_MODULE_25__util_Events__.b._maxListeners - 1);
- }
- }, {
- key: "calculateOffset",
- value: function(_ref6) {
- var props = _ref6.props, graphicalItems = _ref6.graphicalItems, _ref6$xAxisMap = _ref6.xAxisMap, xAxisMap = void 0 === _ref6$xAxisMap ? {} : _ref6$xAxisMap, _ref6$yAxisMap = _ref6.yAxisMap, yAxisMap = void 0 === _ref6$yAxisMap ? {} : _ref6$yAxisMap, width = props.width, height = props.height, children = props.children, margin = props.margin || {}, brushItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__.a), legendItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_11__component_Legend__.a), offsetH = Object.keys(yAxisMap).reduce(function(result, id) {
- var entry = yAxisMap[id], orientation = entry.orientation;
- return entry.mirror || entry.hide ? result : _extends({}, result, _defineProperty({}, orientation, result[orientation] + entry.width));
- }, {
- left: margin.left || 0,
- right: margin.right || 0
- }), offsetV = Object.keys(xAxisMap).reduce(function(result, id) {
- var entry = xAxisMap[id], orientation = entry.orientation;
- return entry.mirror || entry.hide ? result : _extends({}, result, _defineProperty({}, orientation, result[orientation] + entry.height));
- }, {
- top: margin.top || 0,
- bottom: margin.bottom || 0
- }), offset = _extends({}, offsetV, offsetH), brushBottom = offset.bottom;
- if (brushItem && (offset.bottom += brushItem.props.height || __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__.a.defaultProps.height),
- legendItem && this.legendInstance) {
- var legendBox = this.legendInstance.getBBox();
- offset = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.a)(offset, graphicalItems, props, legendBox);
- }
- return _extends({
- brushBottom: brushBottom
- }, offset, {
- width: width - offset.left - offset.right,
- height: height - offset.top - offset.bottom
- });
- }
- }, {
- key: "triggerSyncEvent",
- value: function(data) {
- var syncId = this.props.syncId;
- __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(syncId) || __WEBPACK_IMPORTED_MODULE_25__util_Events__.b.emit(__WEBPACK_IMPORTED_MODULE_25__util_Events__.a, syncId, this.uniqueChartId, data);
- }
- }, {
- key: "filterFormatItem",
- value: function(item, displayName, childIndex) {
- for (var formatedGraphicalItems = this.state.formatedGraphicalItems, i = 0, len = formatedGraphicalItems.length; i < len; i++) {
- var entry = formatedGraphicalItems[i];
- if (entry.item === item || entry.props.key === item.key || displayName === Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.j)(entry.item.type) && childIndex === entry.childIndex) return entry;
- }
- return null;
- }
- }, {
- key: "renderAxis",
- value: function(axisOptions, element, displayName, index) {
- var _props2 = this.props, width = _props2.width, height = _props2.height;
- return __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__.a, _extends({}, axisOptions, {
- className: "recharts-" + axisOptions.axisType + " " + axisOptions.axisType,
- key: element.key || displayName + "-" + index,
- viewBox: {
- x: 0,
- y: 0,
- width: width,
- height: height
- },
- ticksGenerator: this.axesTicksGenerator
- }));
- }
- }, {
- key: "renderLegend",
- value: function() {
- var _this5 = this, formatedGraphicalItems = this.state.formatedGraphicalItems, _props3 = this.props, children = _props3.children, width = _props3.width, height = _props3.height, margin = this.props.margin || {}, legendWidth = width - (margin.left || 0) - (margin.right || 0), legendHeight = height - (margin.top || 0) - (margin.bottom || 0), props = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.q)({
- children: children,
- formatedGraphicalItems: formatedGraphicalItems,
- legendWidth: legendWidth,
- legendHeight: legendHeight,
- legendContent: legendContent
- });
- if (!props) return null;
- var item = props.item, otherProps = _objectWithoutProperties(props, [ "item" ]);
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(item, _extends({}, otherProps, {
- chartWidth: width,
- chartHeight: height,
- margin: margin,
- ref: function(legend) {
- _this5.legendInstance = legend;
- },
- onBBoxUpdate: this.handleLegendBBoxUpdate
- }));
- }
- }, {
- key: "renderTooltip",
- value: function() {
- var children = this.props.children, tooltipItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__.a);
- if (!tooltipItem) return null;
- var _state8 = this.state, isTooltipActive = _state8.isTooltipActive, activeCoordinate = _state8.activeCoordinate, activePayload = _state8.activePayload, activeLabel = _state8.activeLabel, offset = _state8.offset;
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(tooltipItem, {
- viewBox: _extends({}, offset, {
- x: offset.left,
- y: offset.top
- }),
- active: isTooltipActive,
- label: activeLabel,
- payload: isTooltipActive ? activePayload : [],
- coordinate: activeCoordinate
- });
- }
- }, {
- key: "renderActiveDot",
- value: function(option, props) {
- var dot = void 0;
- return dot = Object(__WEBPACK_IMPORTED_MODULE_5_react__.isValidElement)(option) ? Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(option, props) : __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(option) ? option(props) : __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_15__shape_Dot__.a, props),
- __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_9__container_Layer__.a, {
- className: "recharts-active-dot",
- key: props.key
- }, dot);
- }
- }, {
- key: "renderActivePoints",
- value: function(_ref7) {
- var item = _ref7.item, activePoint = _ref7.activePoint, basePoint = _ref7.basePoint, childIndex = _ref7.childIndex, isRange = _ref7.isRange, result = [], key = item.props.key, _item$item$props = item.item.props, activeDot = _item$item$props.activeDot, dataKey = _item$item$props.dataKey, dotProps = _extends({
- index: childIndex,
- dataKey: dataKey,
- cx: activePoint.x,
- cy: activePoint.y,
- r: 4,
- fill: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.r)(item.item),
- strokeWidth: 2,
- stroke: "#fff",
- payload: activePoint.payload,
- value: activePoint.value,
- key: key + "-activePoint-" + childIndex
- }, Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.k)(activeDot), Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.e)(activeDot));
- return result.push(this.renderActiveDot(activeDot, dotProps, childIndex)), basePoint ? result.push(this.renderActiveDot(activeDot, _extends({}, dotProps, {
- cx: basePoint.x,
- cy: basePoint.y,
- key: key + "-basePoint-" + childIndex
- }), childIndex)) : isRange && result.push(null), result;
- }
- }, {
- key: "render",
- value: function() {
- var _this6 = this;
- if (!Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.q)(this)) return null;
- var _props4 = this.props, children = _props4.children, className = _props4.className, width = _props4.width, height = _props4.height, style = _props4.style, compact = _props4.compact, others = _objectWithoutProperties(_props4, [ "children", "className", "width", "height", "style", "compact" ]), attrs = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.k)(others), map = {
- CartesianGrid: {
- handler: this.renderGrid,
- once: !0
- },
- ReferenceArea: {
- handler: this.renderReferenceElement
- },
- ReferenceLine: {
- handler: this.renderReferenceElement
- },
- ReferenceDot: {
- handler: this.renderReferenceElement
- },
- XAxis: {
- handler: this.renderXAxis
- },
- YAxis: {
- handler: this.renderYAxis
- },
- Brush: {
- handler: this.renderBrush,
- once: !0
- },
- Bar: {
- handler: this.renderGraphicChild
- },
- Line: {
- handler: this.renderGraphicChild
- },
- Area: {
- handler: this.renderGraphicChild
- },
- Radar: {
- handler: this.renderGraphicChild
- },
- RadialBar: {
- handler: this.renderGraphicChild
- },
- Scatter: {
- handler: this.renderGraphicChild
- },
- Pie: {
- handler: this.renderGraphicChild
- },
- Tooltip: {
- handler: this.renderCursor,
- once: !0
- },
- PolarGrid: {
- handler: this.renderPolarGrid,
- once: !0
- },
- PolarAngleAxis: {
- handler: this.renderPolarAxis
- },
- PolarRadiusAxis: {
- handler: this.renderPolarAxis
- }
- };
- if (compact) return __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_8__container_Surface__.a, _extends({}, attrs, {
- width: width,
- height: height
- }), Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.p)(children, map));
- var events = this.parseEventsOfWrapper();
- return __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement("div", _extends({
- className: __WEBPACK_IMPORTED_MODULE_7_classnames___default()("recharts-wrapper", className),
- style: _extends({}, style, {
- position: "relative",
- cursor: "default",
- width: width,
- height: height
- })
- }, events, {
- ref: function(node) {
- _this6.container = node;
- }
- }), __WEBPACK_IMPORTED_MODULE_5_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_8__container_Surface__.a, _extends({}, attrs, {
- width: width,
- height: height
- }), Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.p)(children, map)), this.renderLegend(), this.renderTooltip());
- }
- } ]), CategoricalChartWrapper;
- }(__WEBPACK_IMPORTED_MODULE_5_react__.Component), _class.displayName = chartName,
- _class.propTypes = _extends({
- syncId: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number ]),
- compact: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.bool,
- width: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- data: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.object),
- layout: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "horizontal", "vertical" ]),
- stackOffset: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOf([ "sign", "expand", "none", "wiggle", "silhouette" ]),
- throttleDelay: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- margin: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.shape({
- top: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- right: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- bottom: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- left: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number
- }),
- barCategoryGap: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- barGap: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- barSize: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string ]),
- maxBarSize: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number,
- style: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.object,
- className: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string,
- children: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.node), __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.node ]),
- onClick: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseLeave: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseEnter: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseMove: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseDown: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- onMouseUp: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.func,
- reverseStackOrder: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.bool,
- id: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string
- }, propTypes), _class.defaultProps = _extends({
- layout: "horizontal",
- stackOffset: "none",
- barCategoryGap: "10%",
- barGap: 4,
- margin: {
- top: 5,
- right: 5,
- bottom: 5,
- left: 5
- },
- reverseStackOrder: !1
- }, defaultProps), _class.createDefaultState = function(props) {
- var children = props.children, brushItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__.a);
- return {
- chartX: 0,
- chartY: 0,
- dataStartIndex: brushItem && brushItem.props && brushItem.props.startIndex || 0,
- dataEndIndex: brushItem && brushItem.props && brushItem.props.endIndex || props.data && props.data.length - 1 || 0,
- activeTooltipIndex: -1,
- isTooltipActive: !1
- };
- }, _class.hasBar = function(graphicalItems) {
- return !(!graphicalItems || !graphicalItems.length) && graphicalItems.some(function(item) {
- var name = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.j)(item && item.type);
- return name && name.indexOf("Bar") >= 0;
- });
- }, _class.getDisplayedData = function(props, _ref8, item) {
- var graphicalItems = _ref8.graphicalItems, dataStartIndex = _ref8.dataStartIndex, dataEndIndex = _ref8.dataEndIndex, itemsData = (graphicalItems || []).reduce(function(result, child) {
- var itemData = child.props.data;
- return itemData && itemData.length ? [].concat(_toConsumableArray(result), _toConsumableArray(itemData)) : result;
- }, []);
- if (itemsData && itemsData.length > 0) return itemsData;
- if (item && item.props && item.props.data && item.props.data.length > 0) return item.props.data;
- var data = props.data;
- return data && data.length && Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(dataStartIndex) && Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(dataEndIndex) ? data.slice(dataStartIndex, dataEndIndex + 1) : [];
- }, _initialiseProps = function() {
- var _this7 = this;
- this.handleLegendBBoxUpdate = function(box) {
- if (box && _this7.legendInstance) {
- var _state9 = _this7.state, dataStartIndex = _state9.dataStartIndex, dataEndIndex = _state9.dataEndIndex, updateId = _state9.updateId;
- _this7.setState(_this7.updateStateOfAxisMapsOffsetAndStackGroups({
- props: _this7.props,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex,
- updateId: updateId
- }));
- }
- }, this.handleReceiveSyncEvent = function(cId, chartId, data) {
- var _props5 = _this7.props, syncId = _props5.syncId, layout = _props5.layout, updateId = _this7.state.updateId;
- if (syncId === cId && chartId !== _this7.uniqueChartId) {
- var dataStartIndex = data.dataStartIndex, dataEndIndex = data.dataEndIndex;
- if (__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(data.dataStartIndex) && __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(data.dataEndIndex)) if (__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(data.activeTooltipIndex)) _this7.setState(data); else {
- var chartX = data.chartX, chartY = data.chartY, activeTooltipIndex = data.activeTooltipIndex, _state10 = _this7.state, offset = _state10.offset, tooltipTicks = _state10.tooltipTicks;
- if (!offset) return;
- var viewBox = _extends({}, offset, {
- x: offset.left,
- y: offset.top
- }), validateChartX = Math.min(chartX, viewBox.x + viewBox.width), validateChartY = Math.min(chartY, viewBox.y + viewBox.height), activeLabel = tooltipTicks[activeTooltipIndex] && tooltipTicks[activeTooltipIndex].value, activePayload = _this7.getTooltipContent(activeTooltipIndex), activeCoordinate = tooltipTicks[activeTooltipIndex] ? {
- x: "horizontal" === layout ? tooltipTicks[activeTooltipIndex].coordinate : validateChartX,
- y: "horizontal" === layout ? validateChartY : tooltipTicks[activeTooltipIndex].coordinate
- } : originCoordinate;
- _this7.setState(_extends({}, data, {
- activeLabel: activeLabel,
- activeCoordinate: activeCoordinate,
- activePayload: activePayload
- }));
- } else _this7.setState(_extends({
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex
- }, _this7.updateStateOfAxisMapsOffsetAndStackGroups({
- props: _this7.props,
- dataStartIndex: dataStartIndex,
- dataEndIndex: dataEndIndex,
- updateId: updateId
- })));
- }
- }, this.handleBrushChange = function(_ref9) {
- var startIndex = _ref9.startIndex, endIndex = _ref9.endIndex;
- if (startIndex !== _this7.state.dataStartIndex || endIndex !== _this7.state.dataEndIndex) {
- var updateId = _this7.state.updateId;
- _this7.setState(function() {
- return _extends({
- dataStartIndex: startIndex,
- dataEndIndex: endIndex
- }, _this7.updateStateOfAxisMapsOffsetAndStackGroups({
- props: _this7.props,
- dataStartIndex: startIndex,
- dataEndIndex: endIndex,
- updateId: updateId
- }));
- }), _this7.triggerSyncEvent({
- dataStartIndex: startIndex,
- dataEndIndex: endIndex
- });
- }
- }, this.handleMouseEnter = function(e) {
- var onMouseEnter = _this7.props.onMouseEnter, mouse = _this7.getMouseInfo(e);
- if (mouse) {
- var nextState = _extends({}, mouse, {
- isTooltipActive: !0
- });
- _this7.setState(nextState), _this7.triggerSyncEvent(nextState), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onMouseEnter) && onMouseEnter(nextState, e);
- }
- }, this.triggeredAfterMouseMove = function(e) {
- var onMouseMove = _this7.props.onMouseMove, mouse = _this7.getMouseInfo(e), nextState = mouse ? _extends({}, mouse, {
- isTooltipActive: !0
- }) : {
- isTooltipActive: !1
- };
- _this7.setState(nextState), _this7.triggerSyncEvent(nextState), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onMouseMove) && onMouseMove(nextState, e);
- }, this.handleItemMouseEnter = function(el) {
- _this7.setState(function() {
- return {
- isTooltipActive: !0,
- activeItem: el,
- activePayload: el.tooltipPayload,
- activeCoordinate: el.tooltipPosition || {
- x: el.cx,
- y: el.cy
- }
- };
- });
- }, this.handleItemMouseLeave = function() {
- _this7.setState(function() {
- return {
- isTooltipActive: !1
- };
- });
- }, this.handleMouseMove = function(e) {
- e && __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(e.persist) && e.persist(),
- _this7.triggeredAfterMouseMove(e);
- }, this.handleMouseLeave = function(e) {
- var onMouseLeave = _this7.props.onMouseLeave, nextState = {
- isTooltipActive: !1
- };
- _this7.setState(nextState), _this7.triggerSyncEvent(nextState), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onMouseLeave) && onMouseLeave(nextState, e);
- }, this.handleOuterEvent = function(e) {
- var eventName = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.l)(e);
- if (eventName && __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(_this7.props[eventName])) {
- var mouse = _this7.getMouseInfo(e);
- (0, _this7.props[eventName])(mouse, e);
- }
- }, this.handleClick = function(e) {
- var onClick = _this7.props.onClick;
- if (__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onClick)) {
- onClick(_this7.getMouseInfo(e), e);
- }
- }, this.handleMouseDown = function(e) {
- var onMouseDown = _this7.props.onMouseDown;
- if (__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onMouseDown)) {
- onMouseDown(_this7.getMouseInfo(e), e);
- }
- }, this.handleMouseUp = function(e) {
- var onMouseUp = _this7.props.onMouseUp;
- if (__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(onMouseUp)) {
- onMouseUp(_this7.getMouseInfo(e), e);
- }
- }, this.handleTouchMove = function(e) {
- null != e.changedTouches && e.changedTouches.length > 0 && _this7.handleMouseMove(e.changedTouches[0]);
- }, this.verticalCoordinatesGenerator = function(_ref10) {
- var xAxis = _ref10.xAxis, width = _ref10.width, height = _ref10.height, offset = _ref10.offset;
- return Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.m)(__WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__.a.getTicks(_extends({}, __WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__.a.defaultProps, xAxis, {
- ticks: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(xAxis, !0),
- viewBox: {
- x: 0,
- y: 0,
- width: width,
- height: height
- }
- })), offset.left, offset.left + offset.width);
- }, this.horizontalCoordinatesGenerator = function(_ref11) {
- var yAxis = _ref11.yAxis, width = _ref11.width, height = _ref11.height, offset = _ref11.offset;
- return Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.m)(__WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__.a.getTicks(_extends({}, __WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__.a.defaultProps, yAxis, {
- ticks: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(yAxis, !0),
- viewBox: {
- x: 0,
- y: 0,
- width: width,
- height: height
- }
- })), offset.top, offset.top + offset.height);
- }, this.axesTicksGenerator = function(axis) {
- return Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(axis, !0);
- }, this.tooltipTicksGenerator = function(axisMap) {
- var axis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(axisMap), tooltipTicks = Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(axis, !1, !0);
- return {
- tooltipTicks: tooltipTicks,
- orderedTooltipTicks: __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy___default()(tooltipTicks, function(o) {
- return o.coordinate;
- }),
- tooltipAxis: axis,
- tooltipAxisBandSize: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.g)(axis)
- };
- }, this.renderCursor = function(element) {
- var _state11 = _this7.state, isTooltipActive = _state11.isTooltipActive, activeCoordinate = _state11.activeCoordinate, activePayload = _state11.activePayload, offset = _state11.offset;
- if (!(element && element.props.cursor && isTooltipActive && activeCoordinate)) return null;
- var layout = _this7.props.layout, restProps = void 0, cursorComp = __WEBPACK_IMPORTED_MODULE_12__shape_Curve__.a;
- if ("ScatterChart" === chartName) restProps = activeCoordinate, cursorComp = __WEBPACK_IMPORTED_MODULE_13__shape_Cross__.a; else if ("BarChart" === chartName) restProps = _this7.getCursorRectangle(),
- cursorComp = __WEBPACK_IMPORTED_MODULE_16__shape_Rectangle__.a; else if ("radial" === layout) {
- var _getCursorPoints = _this7.getCursorPoints(), cx = _getCursorPoints.cx, cy = _getCursorPoints.cy, radius = _getCursorPoints.radius, startAngle = _getCursorPoints.startAngle, endAngle = _getCursorPoints.endAngle;
- restProps = {
- cx: cx,
- cy: cy,
- startAngle: startAngle,
- endAngle: endAngle,
- innerRadius: radius,
- outerRadius: radius
- }, cursorComp = __WEBPACK_IMPORTED_MODULE_14__shape_Sector__.a;
- } else restProps = {
- points: _this7.getCursorPoints()
- }, cursorComp = __WEBPACK_IMPORTED_MODULE_12__shape_Curve__.a;
- var key = element.key || "_recharts-cursor", cursorProps = _extends({
- stroke: "#ccc"
- }, offset, restProps, Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.k)(element.props.cursor), {
- payload: activePayload,
- key: key,
- className: "recharts-tooltip-cursor"
- });
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.isValidElement)(element.props.cursor) ? Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element.props.cursor, cursorProps) : Object(__WEBPACK_IMPORTED_MODULE_5_react__.createElement)(cursorComp, cursorProps);
- }, this.renderPolarAxis = function(element, displayName, index) {
- var axisType = element.type.axisType, axisMap = _this7.state[axisType + "Map"], axisOption = axisMap[element.props[axisType + "Id"]];
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, _extends({}, axisOption, {
- className: axisType,
- key: element.key || displayName + "-" + index,
- ticks: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(axisOption, !0)
- }));
- }, this.renderXAxis = function(element, displayName, index) {
- var xAxisMap = _this7.state.xAxisMap, axisObj = xAxisMap[element.props.xAxisId];
- return _this7.renderAxis(axisObj, element, displayName, index);
- }, this.renderYAxis = function(element, displayName, index) {
- var yAxisMap = _this7.state.yAxisMap, axisObj = yAxisMap[element.props.yAxisId];
- return _this7.renderAxis(axisObj, element, displayName, index);
- }, this.renderGrid = function(element) {
- var _state12 = _this7.state, xAxisMap = _state12.xAxisMap, yAxisMap = _state12.yAxisMap, offset = _state12.offset, _props6 = _this7.props, width = _props6.width, height = _props6.height, xAxis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(xAxisMap), yAxis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(yAxisMap), props = element.props || {};
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, {
- key: element.key || "grid",
- x: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(props.x) ? props.x : offset.left,
- y: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(props.y) ? props.y : offset.top,
- width: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(props.width) ? props.width : offset.width,
- height: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(props.height) ? props.height : offset.height,
- xAxis: xAxis,
- yAxis: yAxis,
- offset: offset,
- chartWidth: width,
- chartHeight: height,
- verticalCoordinatesGenerator: _this7.verticalCoordinatesGenerator,
- horizontalCoordinatesGenerator: _this7.horizontalCoordinatesGenerator
- });
- }, this.renderPolarGrid = function(element) {
- var _state13 = _this7.state, radiusAxisMap = _state13.radiusAxisMap, angleAxisMap = _state13.angleAxisMap, radiusAxis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(radiusAxisMap), angleAxis = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.b)(angleAxisMap), cx = angleAxis.cx, cy = angleAxis.cy, innerRadius = angleAxis.innerRadius, outerRadius = angleAxis.outerRadius;
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, {
- polarAngles: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(angleAxis, !0).map(function(entry) {
- return entry.coordinate;
- }),
- polarRadius: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.u)(radiusAxis, !0).map(function(entry) {
- return entry.coordinate;
- }),
- cx: cx,
- cy: cy,
- innerRadius: innerRadius,
- outerRadius: outerRadius,
- key: element.key || "polar-grid"
- });
- }, this.renderBrush = function(element) {
- var _props7 = _this7.props, margin = _props7.margin, data = _props7.data, _state14 = _this7.state, offset = _state14.offset, dataStartIndex = _state14.dataStartIndex, dataEndIndex = _state14.dataEndIndex, updateId = _state14.updateId;
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, {
- key: element.key || "_recharts-brush",
- onChange: Object(__WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__.d)(_this7.handleBrushChange, null, element.props.onChange),
- data: data,
- x: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(element.props.x) ? element.props.x : offset.left,
- y: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(element.props.y) ? element.props.y : offset.top + offset.height + offset.brushBottom - (margin.bottom || 0),
- width: Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.h)(element.props.width) ? element.props.width : offset.width,
- startIndex: dataStartIndex,
- endIndex: dataEndIndex,
- updateId: "brush-" + updateId
- });
- }, this.renderReferenceElement = function(element, displayName, index) {
- if (!element) return null;
- var _state15 = _this7.state, xAxisMap = _state15.xAxisMap, yAxisMap = _state15.yAxisMap, offset = _state15.offset, _element$props = element.props, xAxisId = _element$props.xAxisId, yAxisId = _element$props.yAxisId;
- return Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, {
- key: element.key || displayName + "-" + index,
- xAxis: xAxisMap[xAxisId],
- yAxis: yAxisMap[yAxisId],
- viewBox: {
- x: offset.left,
- y: offset.top,
- width: offset.width,
- height: offset.height
- }
- });
- }, this.renderGraphicChild = function(element, displayName, index) {
- var item = _this7.filterFormatItem(element, displayName, index);
- if (!item) return null;
- var graphicalItem = Object(__WEBPACK_IMPORTED_MODULE_5_react__.cloneElement)(element, item.props), _state16 = _this7.state, isTooltipActive = _state16.isTooltipActive, tooltipAxis = _state16.tooltipAxis, activeTooltipIndex = _state16.activeTooltipIndex, activeLabel = _state16.activeLabel, children = _this7.props.children, tooltipItem = Object(__WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__.i)(children, __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__.a), _item$props2 = item.props, points = _item$props2.points, isRange = _item$props2.isRange, baseLine = _item$props2.baseLine, _item$item$props2 = item.item.props, activeDot = _item$item$props2.activeDot;
- if (!_item$item$props2.hide && isTooltipActive && tooltipItem && activeDot && activeTooltipIndex >= 0) {
- var activePoint = void 0, basePoint = void 0;
- if (tooltipAxis.dataKey && !tooltipAxis.allowDuplicatedCategory ? (activePoint = Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.a)(points, "payload." + tooltipAxis.dataKey, activeLabel),
- basePoint = isRange && baseLine && Object(__WEBPACK_IMPORTED_MODULE_21__util_DataUtils__.a)(baseLine, "payload." + tooltipAxis.dataKey, activeLabel)) : (activePoint = points[activeTooltipIndex],
- basePoint = isRange && baseLine && baseLine[activeTooltipIndex]), !__WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default()(activePoint)) return [ graphicalItem ].concat(_toConsumableArray(_this7.renderActivePoints({
- item: item,
- activePoint: activePoint,
- basePoint: basePoint,
- childIndex: activeTooltipIndex,
- isRange: isRange
- })));
- }
- return isRange ? [ graphicalItem, null, null ] : [ graphicalItem, null ];
- };
- }, _temp;
- };
- __webpack_exports__.a = generateCategoricalChart;
-}, function(module, exports, __webpack_require__) {
- var aFunction = __webpack_require__(205);
- module.exports = function(fn, that, length) {
- if (aFunction(fn), void 0 === that) return fn;
- switch (length) {
- case 1:
- return function(a) {
- return fn.call(that, a);
- };
-
- case 2:
- return function(a, b) {
- return fn.call(that, a, b);
- };
-
- case 3:
- return function(a, b, c) {
- return fn.call(that, a, b, c);
- };
- }
- return function() {
- return fn.apply(that, arguments);
- };
- };
-}, function(module, exports, __webpack_require__) {
- var isObject = __webpack_require__(35);
- module.exports = function(it) {
- if (!isObject(it)) throw TypeError(it + " is not an object!");
- return it;
- };
-}, function(module, exports) {
- module.exports = function(exec) {
- try {
- return !!exec();
- } catch (e) {
- return !0;
- }
- };
-}, function(module, exports) {
- var hasOwnProperty = {}.hasOwnProperty;
- module.exports = function(it, key) {
- return hasOwnProperty.call(it, key);
- };
-}, function(module, exports, __webpack_require__) {
- module.exports = {
- default: __webpack_require__(382),
- __esModule: !0
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function capitalize(string) {
- if ("production" !== process.env.NODE_ENV && "string" != typeof string) throw new Error("Material-UI: capitalize(string) expects a string argument.");
- return string.charAt(0).toUpperCase() + string.slice(1);
- }
- function contains(obj, pred) {
- return (0, _keys2.default)(pred).every(function(key) {
- return obj.hasOwnProperty(key) && obj[key] === pred[key];
- });
- }
- function findIndex(arr, pred) {
- for (var predType = void 0 === pred ? "undefined" : (0, _typeof3.default)(pred), i = 0; i < arr.length; i += 1) {
- if ("function" === predType && !0 == !!pred(arr[i], i, arr)) return i;
- if ("object" === predType && contains(arr[i], pred)) return i;
- if (-1 !== [ "string", "number", "boolean" ].indexOf(predType)) return arr.indexOf(pred);
- }
- return -1;
- }
- function find(arr, pred) {
- var index = findIndex(arr, pred);
- return index > -1 ? arr[index] : void 0;
- }
- function createChainedFunction() {
- for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) funcs[_key] = arguments[_key];
- return funcs.filter(function(func) {
- return null != func;
- }).reduce(function(acc, func) {
- return "production" !== process.env.NODE_ENV && (0, _warning2.default)("function" == typeof func, "Material-UI: invalid Argument Type, must only provide functions, undefined, or null."),
- function() {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) args[_key2] = arguments[_key2];
- acc.apply(this, args), func.apply(this, args);
- };
- }, function() {});
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- });
- var _typeof2 = __webpack_require__(101), _typeof3 = _interopRequireDefault(_typeof2), _keys = __webpack_require__(50), _keys2 = _interopRequireDefault(_keys);
- exports.capitalize = capitalize, exports.contains = contains, exports.findIndex = findIndex,
- exports.find = find, exports.createChainedFunction = createChainedFunction;
- var _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning);
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- function getNative(object, key) {
- var value = getValue(object, key);
- return baseIsNative(value) ? value : void 0;
- }
- var baseIsNative = __webpack_require__(564), getValue = __webpack_require__(567);
- module.exports = getNative;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(x) {
- return function() {
- return x;
- };
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _temp2, __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_react__), __WEBPACK_IMPORTED_MODULE_2_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_2_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_prop_types__), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__ = __webpack_require__(688), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__), __WEBPACK_IMPORTED_MODULE_4_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_4_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_classnames__), __WEBPACK_IMPORTED_MODULE_5__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_7__util_DOMUtils__ = __webpack_require__(183), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), BREAKING_SPACES = /[ \f\n\r\t\v\u2028\u2029]+/, calculateWordWidths = function(props) {
- try {
- return {
- wordsWithComputedWidth: (__WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(props.children) ? [] : props.children.toString().split(BREAKING_SPACES)).map(function(word) {
- return {
- word: word,
- width: Object(__WEBPACK_IMPORTED_MODULE_7__util_DOMUtils__.c)(word, props.style).width
- };
- }),
- spaceWidth: Object(__WEBPACK_IMPORTED_MODULE_7__util_DOMUtils__.c)(" ", props.style).width
- };
- } catch (e) {
- return null;
- }
- }, Text = (_temp2 = _class = function(_Component) {
- function Text() {
- var _ref, _temp, _this, _ret;
- _classCallCheck(this, Text);
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
- return _temp = _this = _possibleConstructorReturn(this, (_ref = Text.__proto__ || Object.getPrototypeOf(Text)).call.apply(_ref, [ this ].concat(args))),
- _this.state = {
- wordsByLines: []
- }, _ret = _temp, _possibleConstructorReturn(_this, _ret);
- }
- return _inherits(Text, _Component), _createClass(Text, [ {
- key: "componentWillMount",
- value: function() {
- this.updateWordsByLines(this.props, !0);
- }
- }, {
- key: "componentWillReceiveProps",
- value: function(nextProps) {
- var needCalculate = this.props.children !== nextProps.children || this.props.style !== nextProps.style;
- this.updateWordsByLines(nextProps, needCalculate);
- }
- }, {
- key: "updateWordsByLines",
- value: function(props, needCalculate) {
- if (!props.width && !props.scaleToFit || Object(__WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__.n)()) this.updateWordsWithoutCalculate(props); else {
- if (needCalculate) {
- var wordWidths = calculateWordWidths(props);
- if (!wordWidths) return void this.updateWordsWithoutCalculate(props);
- var wordsWithComputedWidth = wordWidths.wordsWithComputedWidth, spaceWidth = wordWidths.spaceWidth;
- this.wordsWithComputedWidth = wordsWithComputedWidth, this.spaceWidth = spaceWidth;
- }
- var wordsByLines = this.calculateWordsByLines(this.wordsWithComputedWidth, this.spaceWidth, props.width);
- this.setState({
- wordsByLines: wordsByLines
- });
- }
- }
- }, {
- key: "updateWordsWithoutCalculate",
- value: function(props) {
- var words = __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default()(props.children) ? [] : props.children.toString().split(BREAKING_SPACES);
- this.setState({
- wordsByLines: [ {
- words: words
- } ]
- });
- }
- }, {
- key: "calculateWordsByLines",
- value: function(wordsWithComputedWidth, spaceWidth, lineWidth) {
- var scaleToFit = this.props.scaleToFit;
- return wordsWithComputedWidth.reduce(function(result, _ref2) {
- var word = _ref2.word, width = _ref2.width, currentLine = result[result.length - 1];
- if (currentLine && (null == lineWidth || scaleToFit || currentLine.width + width + spaceWidth < lineWidth)) currentLine.words.push(word),
- currentLine.width += width + spaceWidth; else {
- var newLine = {
- words: [ word ],
- width: width
- };
- result.push(newLine);
- }
- return result;
- }, []);
- }
- }, {
- key: "render",
- value: function() {
- var _props = this.props, dx = _props.dx, dy = _props.dy, textAnchor = _props.textAnchor, verticalAnchor = _props.verticalAnchor, scaleToFit = _props.scaleToFit, angle = _props.angle, lineHeight = _props.lineHeight, capHeight = _props.capHeight, className = _props.className, textProps = _objectWithoutProperties(_props, [ "dx", "dy", "textAnchor", "verticalAnchor", "scaleToFit", "angle", "lineHeight", "capHeight", "className" ]), wordsByLines = this.state.wordsByLines;
- if (!Object(__WEBPACK_IMPORTED_MODULE_5__util_DataUtils__.g)(textProps.x) || !Object(__WEBPACK_IMPORTED_MODULE_5__util_DataUtils__.g)(textProps.y)) return null;
- var x = textProps.x + (Object(__WEBPACK_IMPORTED_MODULE_5__util_DataUtils__.h)(dx) ? dx : 0), y = textProps.y + (Object(__WEBPACK_IMPORTED_MODULE_5__util_DataUtils__.h)(dy) ? dy : 0), startDy = void 0;
- switch (verticalAnchor) {
- case "start":
- startDy = __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default()("calc(" + capHeight + ")");
- break;
-
- case "middle":
- startDy = __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default()("calc(" + (wordsByLines.length - 1) / 2 + " * -" + lineHeight + " + (" + capHeight + " / 2))");
- break;
-
- default:
- startDy = __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default()("calc(" + (wordsByLines.length - 1) + " * -" + lineHeight + ")");
- }
- var transforms = [];
- if (scaleToFit) {
- var lineWidth = wordsByLines[0].width;
- transforms.push("scale(" + this.props.width / lineWidth + ")");
- }
- return angle && transforms.push("rotate(" + angle + ", " + x + ", " + y + ")"),
- transforms.length && (textProps.transform = transforms.join(" ")), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("text", _extends({}, Object(__WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__.k)(textProps), {
- x: x,
- y: y,
- className: __WEBPACK_IMPORTED_MODULE_4_classnames___default()("recharts-text", className),
- textAnchor: textAnchor
- }), wordsByLines.map(function(line, index) {
- return __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("tspan", {
- x: x,
- dy: 0 === index ? startDy : lineHeight,
- key: index
- }, line.words.join(" "));
- }));
- }
- } ]), Text;
- }(__WEBPACK_IMPORTED_MODULE_1_react__.Component), _class.propTypes = _extends({}, __WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__.c, {
- scaleToFit: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.bool,
- angle: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.number,
- textAnchor: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.oneOf([ "start", "middle", "end", "inherit" ]),
- verticalAnchor: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.oneOf([ "start", "middle", "end" ]),
- style: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.object
- }), _class.defaultProps = {
- x: 0,
- y: 0,
- lineHeight: "1em",
- capHeight: "0.71em",
- scaleToFit: !1,
- textAnchor: "start",
- verticalAnchor: "end"
- }, _temp2);
- __webpack_exports__.a = Text;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return map;
- }), __webpack_require__.d(__webpack_exports__, "b", function() {
- return slice;
- });
- var array = Array.prototype, map = array.map, slice = array.slice;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_2_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_classnames__), __WEBPACK_IMPORTED_MODULE_3__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_4__util_ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), Dot = Object(__WEBPACK_IMPORTED_MODULE_3__util_PureRender__.a)((_temp = _class2 = function(_Component) {
- function Dot() {
- return _classCallCheck(this, Dot), _possibleConstructorReturn(this, (Dot.__proto__ || Object.getPrototypeOf(Dot)).apply(this, arguments));
- }
- return _inherits(Dot, _Component), _createClass(Dot, [ {
- key: "render",
- value: function() {
- var _props = this.props, cx = _props.cx, cy = _props.cy, r = _props.r, className = _props.className, layerClass = __WEBPACK_IMPORTED_MODULE_2_classnames___default()("recharts-dot", className);
- return cx === +cx && cy === +cy && r === +r ? __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("circle", _extends({}, Object(__WEBPACK_IMPORTED_MODULE_4__util_ReactUtils__.k)(this.props), Object(__WEBPACK_IMPORTED_MODULE_4__util_ReactUtils__.e)(this.props, null, !0), {
- className: layerClass,
- cx: cx,
- cy: cy,
- r: r
- })) : null;
- }
- } ]), Dot;
- }(__WEBPACK_IMPORTED_MODULE_0_react__.Component), _class2.displayName = "Dot", _class2.propTypes = {
- className: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- cx: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- cy: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- r: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number
- }, _class = _temp)) || _class;
- __webpack_exports__.a = Dot;
-}, function(module, exports, __webpack_require__) {
- var IObject = __webpack_require__(134), defined = __webpack_require__(136);
- module.exports = function(it) {
- return IObject(defined(it));
- };
-}, function(module, exports, __webpack_require__) {
- var defined = __webpack_require__(136);
- module.exports = function(it) {
- return Object(defined(it));
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- });
- var _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj) {
- return typeof obj;
- } : function(obj) {
- return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning), _toCss = __webpack_require__(152), _toCss2 = _interopRequireDefault(_toCss), _toCssValue = __webpack_require__(106), _toCssValue2 = _interopRequireDefault(_toCssValue), StyleRule = function() {
- function StyleRule(key, style, options) {
- _classCallCheck(this, StyleRule), this.type = "style", this.isProcessed = !1;
- var sheet = options.sheet, Renderer = options.Renderer, selector = options.selector;
- this.key = key, this.options = options, this.style = style, selector && (this.selectorText = selector),
- this.renderer = sheet ? sheet.renderer : new Renderer();
- }
- return _createClass(StyleRule, [ {
- key: "prop",
- value: function(name, value) {
- if (void 0 === value) return this.style[name];
- if (this.style[name] === value) return this;
- value = this.options.jss.plugins.onChangeValue(value, name, this);
- var isEmpty = null == value || !1 === value, isDefined = name in this.style;
- if (isEmpty && !isDefined) return this;
- var remove = isEmpty && isDefined;
- if (remove ? delete this.style[name] : this.style[name] = value, this.renderable) return remove ? this.renderer.removeProperty(this.renderable, name) : this.renderer.setProperty(this.renderable, name, value),
- this;
- var sheet = this.options.sheet;
- return sheet && sheet.attached && (0, _warning2.default)(!1, 'Rule is not linked. Missing sheet option "link: true".'),
- this;
- }
- }, {
- key: "applyTo",
- value: function(renderable) {
- var json = this.toJSON();
- for (var prop in json) this.renderer.setProperty(renderable, prop, json[prop]);
- return this;
- }
- }, {
- key: "toJSON",
- value: function() {
- var json = {};
- for (var prop in this.style) {
- var value = this.style[prop];
- "object" !== (void 0 === value ? "undefined" : _typeof(value)) ? json[prop] = value : Array.isArray(value) && (json[prop] = (0,
- _toCssValue2.default)(value));
- }
- return json;
- }
- }, {
- key: "toString",
- value: function(options) {
- var sheet = this.options.sheet, link = !!sheet && sheet.options.link, opts = link ? _extends({}, options, {
- allowEmpty: !0
- }) : options;
- return (0, _toCss2.default)(this.selector, this.style, opts);
- }
- }, {
- key: "selector",
- set: function(selector) {
- if (selector !== this.selectorText && (this.selectorText = selector, this.renderable)) {
- if (!this.renderer.setSelector(this.renderable, selector) && this.renderable) {
- var renderable = this.renderer.replaceRule(this.renderable, this);
- renderable && (this.renderable = renderable);
- }
- }
- },
- get: function() {
- return this.selectorText;
- }
- } ]), StyleRule;
- }();
- exports.default = StyleRule;
-}, function(module, exports) {
- var g;
- g = function() {
- return this;
- }();
- try {
- g = g || Function("return this")() || (0, eval)("this");
- } catch (e) {
- "object" == typeof window && (g = window);
- }
- module.exports = g;
-}, function(module, exports, __webpack_require__) {
- function isSymbol(value) {
- return "symbol" == typeof value || isObjectLike(value) && baseGetTag(value) == symbolTag;
- }
- var baseGetTag = __webpack_require__(41), isObjectLike = __webpack_require__(36), symbolTag = "[object Symbol]";
- module.exports = isSymbol;
-}, function(module, exports) {
- function identity(value) {
- return value;
- }
- module.exports = identity;
-}, function(module, exports, __webpack_require__) {
- function baseIteratee(value) {
- return "function" == typeof value ? value : null == value ? identity : "object" == typeof value ? isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value) : property(value);
- }
- var baseMatches = __webpack_require__(671), baseMatchesProperty = __webpack_require__(674), identity = __webpack_require__(62), isArray = __webpack_require__(11), property = __webpack_require__(678);
- module.exports = baseIteratee;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(a, b) {
- return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _class2, _temp2, __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_2_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_classnames__), __WEBPACK_IMPORTED_MODULE_3_react_smooth__ = __webpack_require__(33), __WEBPACK_IMPORTED_MODULE_3_react_smooth___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_react_smooth__), __WEBPACK_IMPORTED_MODULE_4__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), getRectangePath = function(x, y, width, height, radius) {
- var maxRadius = Math.min(Math.abs(width) / 2, Math.abs(height) / 2), sign = height >= 0 ? 1 : -1, clockWise = height >= 0 ? 1 : 0, path = void 0;
- if (maxRadius > 0 && radius instanceof Array) {
- for (var newRadius = [], i = 0; i < 4; i++) newRadius[i] = radius[i] > maxRadius ? maxRadius : radius[i];
- path = "M" + x + "," + (y + sign * newRadius[0]), newRadius[0] > 0 && (path += "A " + newRadius[0] + "," + newRadius[0] + ",0,0," + clockWise + "," + (x + newRadius[0]) + "," + y),
- path += "L " + (x + width - newRadius[1]) + "," + y, newRadius[1] > 0 && (path += "A " + newRadius[1] + "," + newRadius[1] + ",0,0," + clockWise + ",\n " + (x + width) + "," + (y + sign * newRadius[1])),
- path += "L " + (x + width) + "," + (y + height - sign * newRadius[2]), newRadius[2] > 0 && (path += "A " + newRadius[2] + "," + newRadius[2] + ",0,0," + clockWise + ",\n " + (x + width - newRadius[2]) + "," + (y + height)),
- path += "L " + (x + newRadius[3]) + "," + (y + height), newRadius[3] > 0 && (path += "A " + newRadius[3] + "," + newRadius[3] + ",0,0," + clockWise + ",\n " + x + "," + (y + height - sign * newRadius[3])),
- path += "Z";
- } else if (maxRadius > 0 && radius === +radius && radius > 0) {
- var _newRadius = Math.min(maxRadius, radius);
- path = "M " + x + "," + (y + sign * _newRadius) + "\n A " + _newRadius + "," + _newRadius + ",0,0," + clockWise + "," + (x + _newRadius) + "," + y + "\n L " + (x + width - _newRadius) + "," + y + "\n A " + _newRadius + "," + _newRadius + ",0,0," + clockWise + "," + (x + width) + "," + (y + sign * _newRadius) + "\n L " + (x + width) + "," + (y + height - sign * _newRadius) + "\n A " + _newRadius + "," + _newRadius + ",0,0," + clockWise + "," + (x + width - _newRadius) + "," + (y + height) + "\n L " + (x + _newRadius) + "," + (y + height) + "\n A " + _newRadius + "," + _newRadius + ",0,0," + clockWise + "," + x + "," + (y + height - sign * _newRadius) + " Z";
- } else path = "M " + x + "," + y + " h " + width + " v " + height + " h " + -width + " Z";
- return path;
- }, Rectangle = Object(__WEBPACK_IMPORTED_MODULE_4__util_PureRender__.a)((_temp2 = _class2 = function(_Component) {
- function Rectangle() {
- var _ref, _temp, _this, _ret;
- _classCallCheck(this, Rectangle);
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
- return _temp = _this = _possibleConstructorReturn(this, (_ref = Rectangle.__proto__ || Object.getPrototypeOf(Rectangle)).call.apply(_ref, [ this ].concat(args))),
- _this.state = {
- totalLength: -1
- }, _ret = _temp, _possibleConstructorReturn(_this, _ret);
- }
- return _inherits(Rectangle, _Component), _createClass(Rectangle, [ {
- key: "componentDidMount",
- value: function() {
- if (this.node && this.node.getTotalLength) try {
- var totalLength = this.node.getTotalLength();
- totalLength && this.setState({
- totalLength: totalLength
- });
- } catch (err) {}
- }
- }, {
- key: "render",
- value: function() {
- var _this2 = this, _props = this.props, x = _props.x, y = _props.y, width = _props.width, height = _props.height, radius = _props.radius, className = _props.className, totalLength = this.state.totalLength, _props2 = this.props, animationEasing = _props2.animationEasing, animationDuration = _props2.animationDuration, animationBegin = _props2.animationBegin, isAnimationActive = _props2.isAnimationActive, isUpdateAnimationActive = _props2.isUpdateAnimationActive;
- if (x !== +x || y !== +y || width !== +width || height !== +height || 0 === width || 0 === height) return null;
- var layerClass = __WEBPACK_IMPORTED_MODULE_2_classnames___default()("recharts-rectangle", className);
- return isUpdateAnimationActive ? __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_3_react_smooth___default.a, {
- canBegin: totalLength > 0,
- from: {
- width: width,
- height: height,
- x: x,
- y: y
- },
- to: {
- width: width,
- height: height,
- x: x,
- y: y
- },
- duration: animationDuration,
- animationEasing: animationEasing,
- isActive: isUpdateAnimationActive
- }, function(_ref2) {
- var currWidth = _ref2.width, currHeight = _ref2.height, currX = _ref2.x, currY = _ref2.y;
- return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_3_react_smooth___default.a, {
- canBegin: totalLength > 0,
- from: "0px " + (-1 === totalLength ? 1 : totalLength) + "px",
- to: totalLength + "px 0px",
- attributeName: "strokeDasharray",
- begin: animationBegin,
- duration: animationDuration,
- isActive: isAnimationActive,
- easing: animationEasing
- }, __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("path", _extends({}, Object(__WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.k)(_this2.props), Object(__WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.e)(_this2.props), {
- className: layerClass,
- d: getRectangePath(currX, currY, currWidth, currHeight, radius),
- ref: function(node) {
- _this2.node = node;
- }
- })));
- }) : __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("path", _extends({}, Object(__WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.k)(this.props), Object(__WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.e)(this.props), {
- className: layerClass,
- d: getRectangePath(x, y, width, height, radius)
- }));
- }
- } ]), Rectangle;
- }(__WEBPACK_IMPORTED_MODULE_0_react__.Component), _class2.displayName = "Rectangle",
- _class2.propTypes = _extends({}, __WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.c, __WEBPACK_IMPORTED_MODULE_5__util_ReactUtils__.a, {
- className: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- x: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- y: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- radius: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.array ]),
- isAnimationActive: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- isUpdateAnimationActive: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- animationBegin: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- animationDuration: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- animationEasing: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "ease", "ease-in", "ease-out", "ease-in-out", "linear" ])
- }), _class2.defaultProps = {
- x: 0,
- y: 0,
- width: 0,
- height: 0,
- radius: 0,
- isAnimationActive: !1,
- isUpdateAnimationActive: !1,
- animationBegin: 0,
- animationDuration: 1500,
- animationEasing: "ease"
- }, _class = _temp2)) || _class;
- __webpack_exports__.a = Rectangle;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_0_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_2_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_react__), __WEBPACK_IMPORTED_MODULE_3_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_3_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_prop_types__), __WEBPACK_IMPORTED_MODULE_4_d3_shape__ = __webpack_require__(172), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), CURVE_FACTORIES = {
- curveBasisClosed: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.c,
- curveBasisOpen: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.d,
- curveBasis: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.b,
- curveLinearClosed: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.f,
- curveLinear: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.e,
- curveMonotoneX: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.g,
- curveMonotoneY: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.h,
- curveNatural: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.i,
- curveStep: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.j,
- curveStepAfter: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.k,
- curveStepBefore: __WEBPACK_IMPORTED_MODULE_4_d3_shape__.l
- }, defined = function(p) {
- return p.x === +p.x && p.y === +p.y;
- }, getX = function(p) {
- return p.x;
- }, getY = function(p) {
- return p.y;
- }, getCurveFactory = function(type, layout) {
- if (__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default()(type)) return type;
- var name = "curve" + type.slice(0, 1).toUpperCase() + type.slice(1);
- return "curveMonotone" === name && layout ? CURVE_FACTORIES[name + ("vertical" === layout ? "Y" : "X")] : CURVE_FACTORIES[name] || __WEBPACK_IMPORTED_MODULE_4_d3_shape__.e;
- }, Curve = Object(__WEBPACK_IMPORTED_MODULE_6__util_PureRender__.a)((_temp = _class2 = function(_Component) {
- function Curve() {
- return _classCallCheck(this, Curve), _possibleConstructorReturn(this, (Curve.__proto__ || Object.getPrototypeOf(Curve)).apply(this, arguments));
- }
- return _inherits(Curve, _Component), _createClass(Curve, [ {
- key: "getPath",
- value: function() {
- var _props = this.props, type = _props.type, points = _props.points, baseLine = _props.baseLine, layout = _props.layout, connectNulls = _props.connectNulls, curveFactory = getCurveFactory(type, layout), formatPoints = connectNulls ? points.filter(function(entry) {
- return defined(entry);
- }) : points, lineFunction = void 0;
- if (__WEBPACK_IMPORTED_MODULE_0_lodash_isArray___default()(baseLine)) {
- var areaPoints = formatPoints.map(function(entry, index) {
- return _extends({}, entry, {
- base: baseLine[index]
- });
- });
- return lineFunction = "vertical" === layout ? Object(__WEBPACK_IMPORTED_MODULE_4_d3_shape__.a)().y(getY).x1(getX).x0(function(d) {
- return d.base.x;
- }) : Object(__WEBPACK_IMPORTED_MODULE_4_d3_shape__.a)().x(getX).y1(getY).y0(function(d) {
- return d.base.y;
- }), lineFunction.defined(defined).curve(curveFactory), lineFunction(areaPoints);
- }
- return lineFunction = "vertical" === layout && Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(baseLine) ? Object(__WEBPACK_IMPORTED_MODULE_4_d3_shape__.a)().y(getY).x1(getX).x0(baseLine) : Object(__WEBPACK_IMPORTED_MODULE_8__util_DataUtils__.h)(baseLine) ? Object(__WEBPACK_IMPORTED_MODULE_4_d3_shape__.a)().x(getX).y1(getY).y0(baseLine) : Object(__WEBPACK_IMPORTED_MODULE_4_d3_shape__.m)().x(getX).y(getY),
- lineFunction.defined(defined).curve(curveFactory), lineFunction(formatPoints);
- }
- }, {
- key: "render",
- value: function() {
- var _props2 = this.props, className = _props2.className, points = _props2.points, path = _props2.path, pathRef = _props2.pathRef;
- if (!(points && points.length || path)) return null;
- var realPath = points && points.length ? this.getPath() : path;
- return __WEBPACK_IMPORTED_MODULE_2_react___default.a.createElement("path", _extends({}, Object(__WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__.k)(this.props), Object(__WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__.e)(this.props, null, !0), {
- className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()("recharts-curve", className),
- d: realPath,
- ref: pathRef
- }));
- }
- } ]), Curve;
- }(__WEBPACK_IMPORTED_MODULE_2_react__.Component), _class2.displayName = "Curve",
- _class2.propTypes = _extends({}, __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__.c, {
- className: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.string,
- type: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.oneOf([ "basis", "basisClosed", "basisOpen", "linear", "linearClosed", "natural", "monotoneX", "monotoneY", "monotone", "step", "stepBefore", "stepAfter" ]), __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.func ]),
- layout: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.oneOf([ "horizontal", "vertical" ]),
- baseLine: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.array ]),
- points: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.object),
- connectNulls: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.bool,
- path: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.string,
- pathRef: __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.func
- }), _class2.defaultProps = {
- type: "linear",
- points: [],
- connectNulls: !1
- }, _class = _temp)) || _class;
- __webpack_exports__.a = Curve;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__),
- __webpack_require__(1)), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__ = __webpack_require__(4), _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), XAxis = Object(__WEBPACK_IMPORTED_MODULE_2__util_PureRender__.a)((_temp = _class2 = function(_Component) {
- function XAxis() {
- return _classCallCheck(this, XAxis), _possibleConstructorReturn(this, (XAxis.__proto__ || Object.getPrototypeOf(XAxis)).apply(this, arguments));
- }
- return _inherits(XAxis, _Component), _createClass(XAxis, [ {
- key: "render",
- value: function() {
- return null;
- }
- } ]), XAxis;
- }(__WEBPACK_IMPORTED_MODULE_0_react__.Component), _class2.displayName = "XAxis",
- _class2.propTypes = {
- allowDecimals: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- allowDuplicatedCategory: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- hide: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- name: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- unit: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- xAxisId: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- domain: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "auto", "dataMin", "dataMax" ]) ])),
- dataKey: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func ]),
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- mirror: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- orientation: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "top", "bottom" ]),
- type: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "number", "category" ]),
- ticks: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.array,
- tickCount: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- tickFormatter: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func,
- padding: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.shape({
- left: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- right: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number
- }),
- allowDataOverflow: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- scale: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf(__WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__.d), __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func ]),
- tick: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.element ]),
- axisLine: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object ]),
- tickLine: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object ]),
- minTickGap: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- tickSize: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- interval: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "preserveStart", "preserveEnd", "preserveStartEnd" ]) ]),
- reversed: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool
- }, _class2.defaultProps = {
- allowDecimals: !0,
- hide: !1,
- orientation: "bottom",
- width: 0,
- height: 30,
- mirror: !1,
- xAxisId: 0,
- tickCount: 5,
- type: "category",
- domain: [ 0, "auto" ],
- padding: {
- left: 0,
- right: 0
- },
- allowDataOverflow: !1,
- scale: "auto",
- reversed: !1,
- allowDuplicatedCategory: !0
- }, _class = _temp)) || _class;
- __webpack_exports__.a = XAxis;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__),
- __webpack_require__(1)), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2__util_PureRender__ = __webpack_require__(5), _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), YAxis = Object(__WEBPACK_IMPORTED_MODULE_2__util_PureRender__.a)((_temp = _class2 = function(_Component) {
- function YAxis() {
- return _classCallCheck(this, YAxis), _possibleConstructorReturn(this, (YAxis.__proto__ || Object.getPrototypeOf(YAxis)).apply(this, arguments));
- }
- return _inherits(YAxis, _Component), _createClass(YAxis, [ {
- key: "render",
- value: function() {
- return null;
- }
- } ]), YAxis;
- }(__WEBPACK_IMPORTED_MODULE_0_react__.Component), _class2.displayName = "YAxis",
- _class2.propTypes = {
- allowDecimals: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- allowDuplicatedCategory: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- hide: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- name: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- unit: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- yAxisId: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number ]),
- domain: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "auto", "dataMin", "dataMax" ]) ])),
- dataKey: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func ]),
- ticks: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.array,
- tickCount: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- tickFormatter: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func,
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- mirror: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- orientation: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "left", "right" ]),
- type: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "number", "category" ]),
- padding: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.shape({
- top: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- bottom: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number
- }),
- allowDataOverflow: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool,
- scale: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "auto", "linear", "pow", "sqrt", "log", "identity", "time", "band", "point", "ordinal", "quantile", "quantize", "utcTime", "sequential", "threshold" ]), __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func ]),
- tick: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.element ]),
- axisLine: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object ]),
- tickLine: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object ]),
- minTickGap: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- tickSize: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- interval: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOf([ "preserveStart", "preserveEnd", "preserveStartEnd" ]) ]),
- reversed: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.bool
- }, _class2.defaultProps = {
- allowDuplicatedCategory: !0,
- allowDecimals: !0,
- hide: !1,
- orientation: "left",
- width: 60,
- height: 0,
- mirror: !1,
- yAxisId: 0,
- tickCount: 5,
- type: "number",
- domain: [ 0, "auto" ],
- padding: {
- top: 0,
- bottom: 0
- },
- allowDataOverflow: !1,
- scale: "auto",
- reversed: !1
- }, _class = _temp)) || _class;
- __webpack_exports__.a = YAxis;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function toObject(val) {
- if (null === val || void 0 === val) throw new TypeError("Object.assign cannot be called with null or undefined");
- return Object(val);
- }
- var getOwnPropertySymbols = Object.getOwnPropertySymbols, hasOwnProperty = Object.prototype.hasOwnProperty, propIsEnumerable = Object.prototype.propertyIsEnumerable;
- module.exports = function() {
- try {
- if (!Object.assign) return !1;
- var test1 = new String("abc");
- if (test1[5] = "de", "5" === Object.getOwnPropertyNames(test1)[0]) return !1;
- for (var test2 = {}, i = 0; i < 10; i++) test2["_" + String.fromCharCode(i)] = i;
- if ("0123456789" !== Object.getOwnPropertyNames(test2).map(function(n) {
- return test2[n];
- }).join("")) return !1;
- var test3 = {};
- return "abcdefghijklmnopqrst".split("").forEach(function(letter) {
- test3[letter] = letter;
- }), "abcdefghijklmnopqrst" === Object.keys(Object.assign({}, test3)).join("");
- } catch (err) {
- return !1;
- }
- }() ? Object.assign : function(target, source) {
- for (var from, symbols, to = toObject(target), s = 1; s < arguments.length; s++) {
- from = Object(arguments[s]);
- for (var key in from) hasOwnProperty.call(from, key) && (to[key] = from[key]);
- if (getOwnPropertySymbols) {
- symbols = getOwnPropertySymbols(from);
- for (var i = 0; i < symbols.length; i++) propIsEnumerable.call(from, symbols[i]) && (to[symbols[i]] = from[symbols[i]]);
- }
- }
- return to;
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- function invariant(condition, format, a, b, c, d, e, f) {
- if (validateFormat(format), !condition) {
- var error;
- if (void 0 === format) error = new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings."); else {
- var args = [ a, b, c, d, e, f ], argIndex = 0;
- error = new Error(format.replace(/%s/g, function() {
- return args[argIndex++];
- })), error.name = "Invariant Violation";
- }
- throw error.framesToPop = 1, error;
- }
- }
- var validateFormat = function(format) {};
- "production" !== process.env.NODE_ENV && (validateFormat = function(format) {
- if (void 0 === format) throw new Error("invariant requires an error message argument");
- }), module.exports = invariant;
- }).call(exports, __webpack_require__(2));
-}, function(module, exports) {
- module.exports = function(bitmap, value) {
- return {
- enumerable: !(1 & bitmap),
- configurable: !(2 & bitmap),
- writable: !(4 & bitmap),
- value: value
- };
- };
-}, function(module, exports, __webpack_require__) {
- var $keys = __webpack_require__(208), enumBugKeys = __webpack_require__(140);
- module.exports = Object.keys || function(O) {
- return $keys(O, enumBugKeys);
- };
-}, function(module, exports) {
- module.exports = {};
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function createBreakpoints(breakpoints) {
- function up(key) {
- return "@media (min-width:" + ("number" == typeof values[key] ? values[key] : key) + unit + ")";
- }
- function down(key) {
- var endIndex = keys.indexOf(key) + 1, upperbound = values[keys[endIndex]];
- return endIndex === keys.length ? up("xs") : "@media (max-width:" + (("number" == typeof upperbound && endIndex > 0 ? upperbound : key) - step / 100) + unit + ")";
- }
- function between(start, end) {
- var endIndex = keys.indexOf(end) + 1;
- return endIndex === keys.length ? up(start) : "@media (min-width:" + values[start] + unit + ") and (max-width:" + (values[keys[endIndex]] - step / 100) + unit + ")";
- }
- function only(key) {
- return between(key, key);
- }
- function width(key) {
- return values[key];
- }
- var _breakpoints$values = breakpoints.values, values = void 0 === _breakpoints$values ? {
- xs: 0,
- sm: 600,
- md: 960,
- lg: 1280,
- xl: 1920
- } : _breakpoints$values, _breakpoints$unit = breakpoints.unit, unit = void 0 === _breakpoints$unit ? "px" : _breakpoints$unit, _breakpoints$step = breakpoints.step, step = void 0 === _breakpoints$step ? 5 : _breakpoints$step, other = (0,
- _objectWithoutProperties3.default)(breakpoints, [ "values", "unit", "step" ]);
- return (0, _extends3.default)({
- keys: keys,
- values: values,
- up: up,
- down: down,
- between: between,
- only: only,
- width: width
- }, other);
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- }), exports.keys = void 0;
- var _extends2 = __webpack_require__(6), _extends3 = _interopRequireDefault(_extends2), _objectWithoutProperties2 = __webpack_require__(7), _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
- exports.default = createBreakpoints;
- var keys = exports.keys = [ "xs", "sm", "md", "lg", "xl" ];
-}, function(module, exports, __webpack_require__) {
- "use strict";
- exports.__esModule = !0;
- var _getDisplayName = __webpack_require__(226), _getDisplayName2 = function(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }(_getDisplayName), wrapDisplayName = function(BaseComponent, hocName) {
- return hocName + "(" + (0, _getDisplayName2.default)(BaseComponent) + ")";
- };
- exports.default = wrapDisplayName;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- Object.defineProperty(exports, "__esModule", {
- value: !0
- });
- var _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), _createRule = __webpack_require__(107), _createRule2 = _interopRequireDefault(_createRule), _linkRule = __webpack_require__(231), _linkRule2 = _interopRequireDefault(_linkRule), _StyleRule = __webpack_require__(59), _StyleRule2 = _interopRequireDefault(_StyleRule), _escape = __webpack_require__(428), _escape2 = _interopRequireDefault(_escape), RuleList = function() {
- function RuleList(options) {
- _classCallCheck(this, RuleList), this.map = {}, this.raw = {}, this.index = [],
- this.options = options, this.classes = options.classes;
- }
- return _createClass(RuleList, [ {
- key: "add",
- value: function(name, decl, options) {
- var _options = this.options, parent = _options.parent, sheet = _options.sheet, jss = _options.jss, Renderer = _options.Renderer, generateClassName = _options.generateClassName;
- options = _extends({
- classes: this.classes,
- parent: parent,
- sheet: sheet,
- jss: jss,
- Renderer: Renderer,
- generateClassName: generateClassName
- }, options), !options.selector && this.classes[name] && (options.selector = "." + (0,
- _escape2.default)(this.classes[name])), this.raw[name] = decl;
- var rule = (0, _createRule2.default)(name, decl, options), className = void 0;
- !options.selector && rule instanceof _StyleRule2.default && (className = generateClassName(rule, sheet),
- rule.selector = "." + (0, _escape2.default)(className)), this.register(rule, className);
- var index = void 0 === options.index ? this.index.length : options.index;
- return this.index.splice(index, 0, rule), rule;
- }
- }, {
- key: "get",
- value: function(name) {
- return this.map[name];
- }
- }, {
- key: "remove",
- value: function(rule) {
- this.unregister(rule), this.index.splice(this.indexOf(rule), 1);
- }
- }, {
- key: "indexOf",
- value: function(rule) {
- return this.index.indexOf(rule);
- }
- }, {
- key: "process",
- value: function() {
- var plugins = this.options.jss.plugins;
- this.index.slice(0).forEach(plugins.onProcessRule, plugins);
- }
- }, {
- key: "register",
- value: function(rule, className) {
- this.map[rule.key] = rule, rule instanceof _StyleRule2.default && (this.map[rule.selector] = rule,
- className && (this.classes[rule.key] = className));
- }
- }, {
- key: "unregister",
- value: function(rule) {
- delete this.map[rule.key], rule instanceof _StyleRule2.default && (delete this.map[rule.selector],
- delete this.classes[rule.key]);
- }
- }, {
- key: "update",
- value: function(name, data) {
- var _options2 = this.options, plugins = _options2.jss.plugins, sheet = _options2.sheet;
- if ("string" == typeof name) return void plugins.onUpdate(data, this.get(name), sheet);
- for (var index = 0; index < this.index.length; index++) plugins.onUpdate(name, this.index[index], sheet);
- }
- }, {
- key: "link",
- value: function(cssRules) {
- for (var map = this.options.sheet.renderer.getUnescapedKeysMap(this.index), i = 0; i < cssRules.length; i++) {
- var cssRule = cssRules[i], _key = this.options.sheet.renderer.getKey(cssRule);
- map[_key] && (_key = map[_key]);
- var rule = this.map[_key];
- rule && (0, _linkRule2.default)(rule, cssRule);
- }
- }
- }, {
- key: "toString",
- value: function(options) {
- for (var str = "", sheet = this.options.sheet, link = !!sheet && sheet.options.link, index = 0; index < this.index.length; index++) {
- var rule = this.index[index], css = rule.toString(options);
- (css || link) && (str && (str += "\n"), str += css);
- }
- return str;
- }
- } ]), RuleList;
- }();
- exports.default = RuleList;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: !0
- });
- var _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, menuSkeletons = [ {
- id: "home",
- menu: {
- title: "Home",
- icon: "home"
- }
- }, {
- id: "chain",
- menu: {
- title: "Chain",
- icon: "link"
- }
- }, {
- id: "txpool",
- menu: {
- title: "TxPool",
- icon: "credit-card"
- }
- }, {
- id: "network",
- menu: {
- title: "Network",
- icon: "globe"
- }
- }, {
- id: "system",
- menu: {
- title: "System",
- icon: "tachometer"
- }
- }, {
- id: "logs",
- menu: {
- title: "Logs",
- icon: "list"
- }
- } ];
- exports.MENU = new Map(menuSkeletons.map(function(_ref) {
- var id = _ref.id, menu = _ref.menu;
- return [ id, _extends({
- id: id
- }, menu) ];
- })), exports.DURATION = 200, exports.styles = {
- light: {
- color: "rgba(255, 255, 255, 0.54)"
- }
- };
-}, function(module, exports, __webpack_require__) {
- var root = __webpack_require__(32), Symbol = root.Symbol;
- module.exports = Symbol;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function Surface(props) {
- var children = props.children, width = props.width, height = props.height, viewBox = props.viewBox, className = props.className, style = props.style, others = _objectWithoutProperties(props, [ "children", "width", "height", "viewBox", "className", "style" ]), svgView = viewBox || {
- width: width,
- height: height,
- x: 0,
- y: 0
- }, layerClass = __WEBPACK_IMPORTED_MODULE_2_classnames___default()("recharts-surface", className), attrs = Object(__WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__.k)(others);
- return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("svg", _extends({}, attrs, {
- className: layerClass,
- width: width,
- height: height,
- style: style,
- viewBox: svgView.x + " " + svgView.y + " " + svgView.width + " " + svgView.height,
- version: "1.1"
- }), children);
- }
- var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_2_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_classnames__), __WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, propTypes = {
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number.isRequired,
- height: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number.isRequired,
- viewBox: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.shape({
- x: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- y: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- height: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number
- }),
- className: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- style: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object,
- children: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node), __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node ])
- };
- Surface.propTypes = propTypes, __webpack_exports__.a = Surface;
-}, function(module, exports) {
- function arrayMap(array, iteratee) {
- for (var index = -1, length = null == array ? 0 : array.length, result = Array(length); ++index < length; ) result[index] = iteratee(array[index], index, array);
- return result;
- }
- module.exports = arrayMap;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- var __WEBPACK_IMPORTED_MODULE_0__src_path__ = __webpack_require__(586);
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_path__.a;
- });
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function acos(x) {
- return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
- }
- function asin(x) {
- return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
- }
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return abs;
- }), __webpack_require__.d(__webpack_exports__, "d", function() {
- return atan2;
- }), __webpack_require__.d(__webpack_exports__, "e", function() {
- return cos;
- }), __webpack_require__.d(__webpack_exports__, "h", function() {
- return max;
- }), __webpack_require__.d(__webpack_exports__, "i", function() {
- return min;
- }), __webpack_require__.d(__webpack_exports__, "k", function() {
- return sin;
- }), __webpack_require__.d(__webpack_exports__, "l", function() {
- return sqrt;
- }), __webpack_require__.d(__webpack_exports__, "f", function() {
- return epsilon;
- }), __webpack_require__.d(__webpack_exports__, "j", function() {
- return pi;
- }), __webpack_require__.d(__webpack_exports__, "g", function() {
- return halfPi;
- }), __webpack_require__.d(__webpack_exports__, "m", function() {
- return tau;
- }), __webpack_exports__.b = acos, __webpack_exports__.c = asin;
- var abs = Math.abs, atan2 = Math.atan2, cos = Math.cos, max = Math.max, min = Math.min, sin = Math.sin, sqrt = Math.sqrt, epsilon = 1e-12, pi = Math.PI, halfPi = pi / 2, tau = 2 * pi;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(series, order) {
- if ((n = series.length) > 1) for (var j, s0, n, i = 1, s1 = series[order[0]], m = s1.length; i < n; ++i) for (s0 = s1,
- s1 = series[order[i]], j = 0; j < m; ++j) s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(series) {
- for (var n = series.length, o = new Array(n); --n >= 0; ) o[n] = n;
- return o;
- };
-}, function(module, exports, __webpack_require__) {
- function isArrayLike(value) {
- return null != value && isLength(value.length) && !isFunction(value);
- }
- var isFunction = __webpack_require__(8), isLength = __webpack_require__(181);
- module.exports = isArrayLike;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function Cell() {
- return null;
- }
- var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1__util_ReactUtils__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__),
- __webpack_require__(4)), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- };
- Cell.propTypes = _extends({}, __WEBPACK_IMPORTED_MODULE_1__util_ReactUtils__.c),
- Cell.displayName = "Cell", __webpack_exports__.a = Cell;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(x) {
- return null === x ? NaN : +x;
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function linearish(scale) {
- var domain = scale.domain;
- return scale.ticks = function(count) {
- var d = domain();
- return Object(__WEBPACK_IMPORTED_MODULE_0_d3_array__.h)(d[0], d[d.length - 1], null == count ? 10 : count);
- }, scale.tickFormat = function(count, specifier) {
- return Object(__WEBPACK_IMPORTED_MODULE_3__tickFormat__.a)(domain(), count, specifier);
- }, scale.nice = function(count) {
- null == count && (count = 10);
- var step, d = domain(), i0 = 0, i1 = d.length - 1, start = d[i0], stop = d[i1];
- return stop < start && (step = start, start = stop, stop = step, step = i0, i0 = i1,
- i1 = step), step = Object(__WEBPACK_IMPORTED_MODULE_0_d3_array__.f)(start, stop, count),
- step > 0 ? (start = Math.floor(start / step) * step, stop = Math.ceil(stop / step) * step,
- step = Object(__WEBPACK_IMPORTED_MODULE_0_d3_array__.f)(start, stop, count)) : step < 0 && (start = Math.ceil(start * step) / step,
- stop = Math.floor(stop * step) / step, step = Object(__WEBPACK_IMPORTED_MODULE_0_d3_array__.f)(start, stop, count)),
- step > 0 ? (d[i0] = Math.floor(start / step) * step, d[i1] = Math.ceil(stop / step) * step,
- domain(d)) : step < 0 && (d[i0] = Math.ceil(start * step) / step, d[i1] = Math.floor(stop * step) / step,
- domain(d)), scale;
- }, scale;
- }
- function linear() {
- var scale = Object(__WEBPACK_IMPORTED_MODULE_2__continuous__.b)(__WEBPACK_IMPORTED_MODULE_2__continuous__.c, __WEBPACK_IMPORTED_MODULE_1_d3_interpolate__.c);
- return scale.copy = function() {
- return Object(__WEBPACK_IMPORTED_MODULE_2__continuous__.a)(scale, linear());
- }, linearish(scale);
- }
- __webpack_exports__.b = linearish, __webpack_exports__.a = linear;
- var __WEBPACK_IMPORTED_MODULE_0_d3_array__ = __webpack_require__(37), __WEBPACK_IMPORTED_MODULE_1_d3_interpolate__ = __webpack_require__(89), __WEBPACK_IMPORTED_MODULE_2__continuous__ = __webpack_require__(125), __WEBPACK_IMPORTED_MODULE_3__tickFormat__ = __webpack_require__(742);
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- var __WEBPACK_IMPORTED_MODULE_0__src_value__ = __webpack_require__(186);
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return __WEBPACK_IMPORTED_MODULE_0__src_value__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_5__src_number__ = (__webpack_require__(310), __webpack_require__(189),
- __webpack_require__(308), __webpack_require__(311), __webpack_require__(124));
- __webpack_require__.d(__webpack_exports__, "c", function() {
- return __WEBPACK_IMPORTED_MODULE_5__src_number__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_7__src_round__ = (__webpack_require__(312), __webpack_require__(732));
- __webpack_require__.d(__webpack_exports__, "d", function() {
- return __WEBPACK_IMPORTED_MODULE_7__src_round__.a;
- });
- var __WEBPACK_IMPORTED_MODULE_15__src_cubehelix__ = (__webpack_require__(313), __webpack_require__(733),
- __webpack_require__(736), __webpack_require__(307), __webpack_require__(737), __webpack_require__(738),
- __webpack_require__(739), __webpack_require__(740));
- __webpack_require__.d(__webpack_exports__, "b", function() {
- return __WEBPACK_IMPORTED_MODULE_15__src_cubehelix__.a;
- });
- __webpack_require__(741);
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function linear(a, d) {
- return function(t) {
- return a + t * d;
- };
- }
- function exponential(a, b, y) {
- return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
- return Math.pow(a + t * b, y);
- };
- }
- function hue(a, b) {
- var d = b - a;
- return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : Object(__WEBPACK_IMPORTED_MODULE_0__constant__.a)(isNaN(a) ? b : a);
- }
- function gamma(y) {
- return 1 == (y = +y) ? nogamma : function(a, b) {
- return b - a ? exponential(a, b, y) : Object(__WEBPACK_IMPORTED_MODULE_0__constant__.a)(isNaN(a) ? b : a);
- };
- }
- function nogamma(a, b) {
- var d = b - a;
- return d ? linear(a, d) : Object(__WEBPACK_IMPORTED_MODULE_0__constant__.a)(isNaN(a) ? b : a);
- }
- __webpack_exports__.c = hue, __webpack_exports__.b = gamma, __webpack_exports__.a = nogamma;
- var __WEBPACK_IMPORTED_MODULE_0__constant__ = __webpack_require__(309);
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- __webpack_exports__.a = function(s) {
- return s.match(/.{6}/g).map(function(x) {
- return "#" + x;
- });
- };
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _objectWithoutProperties(obj, keys) {
- var target = {};
- for (var i in obj) keys.indexOf(i) >= 0 || Object.prototype.hasOwnProperty.call(obj, i) && (target[i] = obj[i]);
- return target;
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
- }
- function _possibleConstructorReturn(self, call) {
- if (!self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- return !call || "object" != typeof call && "function" != typeof call ? self : call;
- }
- function _inherits(subClass, superClass) {
- if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass);
- }
- var _class, _temp, __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__), __WEBPACK_IMPORTED_MODULE_1_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_1_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_prop_types__), __WEBPACK_IMPORTED_MODULE_2__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, _createClass = function() {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0,
- "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function(Constructor, protoProps, staticProps) {
- return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps),
- Constructor;
- };
- }(), ErrorBar = (_temp = _class = function(_Component) {
- function ErrorBar() {
- return _classCallCheck(this, ErrorBar), _possibleConstructorReturn(this, (ErrorBar.__proto__ || Object.getPrototypeOf(ErrorBar)).apply(this, arguments));
- }
- return _inherits(ErrorBar, _Component), _createClass(ErrorBar, [ {
- key: "renderErrorBars",
- value: function() {
- var _props = this.props, offset = _props.offset, layout = _props.layout, width = _props.width, dataKey = _props.dataKey, data = _props.data, dataPointFormatter = _props.dataPointFormatter, xAxis = _props.xAxis, yAxis = _props.yAxis, others = _objectWithoutProperties(_props, [ "offset", "layout", "width", "dataKey", "data", "dataPointFormatter", "xAxis", "yAxis" ]), props = Object(__WEBPACK_IMPORTED_MODULE_3__util_ReactUtils__.k)(others);
- return data.map(function(entry, i) {
- var _dataPointFormatter = dataPointFormatter(entry, dataKey), x = _dataPointFormatter.x, y = _dataPointFormatter.y, value = _dataPointFormatter.value, errorVal = _dataPointFormatter.errorVal;
- if (!errorVal) return null;
- var xMid = void 0, yMid = void 0, xMin = void 0, yMin = void 0, xMax = void 0, yMax = void 0, scale = void 0, coordsTop = void 0, coordsMid = void 0, coordsBot = void 0, lowBound = void 0, highBound = void 0;
- return Array.isArray(errorVal) ? (lowBound = errorVal[0], highBound = errorVal[1]) : (lowBound = errorVal,
- highBound = errorVal), "vertical" === layout ? (scale = xAxis.scale, xMid = value,
- yMid = y + offset, xMin = scale(xMid - lowBound), yMin = yMid + width, xMax = scale(xMid + highBound),
- yMax = yMid - width, coordsTop = {
- x1: xMax,
- y1: yMin,
- x2: xMax,
- y2: yMax
- }, coordsMid = {
- x1: xMin,
- y1: yMid,
- x2: xMax,
- y2: yMid
- }, coordsBot = {
- x1: xMin,
- y1: yMin,
- x2: xMin,
- y2: yMax
- }) : "horizontal" === layout && (scale = yAxis.scale, xMid = x + offset, yMid = value,
- xMin = xMid - width, xMax = xMid + width, yMin = scale(yMid - lowBound), yMax = scale(yMid + highBound),
- coordsTop = {
- x1: xMin,
- y1: yMax,
- x2: xMax,
- y2: yMax
- }, coordsMid = {
- x1: xMid,
- y1: yMin,
- x2: xMid,
- y2: yMax
- }, coordsBot = {
- x1: xMin,
- y1: yMin,
- x2: xMax,
- y2: yMin
- }), __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_2__container_Layer__.a, _extends({
- className: "recharts-errorBar",
- key: i
- }, props), __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("line", coordsTop), __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("line", coordsMid), __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement("line", coordsBot));
- });
- }
- }, {
- key: "render",
- value: function() {
- return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_2__container_Layer__.a, {
- className: "recharts-errorBars"
- }, this.renderErrorBars());
- }
- } ]), ErrorBar;
- }(__WEBPACK_IMPORTED_MODULE_0_react__.Component), _class.propTypes = {
- dataKey: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number, __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func ]).isRequired,
- data: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.array,
- xAxis: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object,
- yAxis: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.object,
- layout: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- dataPointFormatter: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.func,
- stroke: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.string,
- strokeWidth: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- width: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number,
- offset: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.number
- }, _class.defaultProps = {
- stroke: "black",
- strokeWidth: 1.5,
- width: 5,
- offset: 0,
- layout: "horizontal"
- }, _temp);
- __webpack_exports__.a = ErrorBar;
-}, function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- function _defineProperty(obj, key, value) {
- return key in obj ? Object.defineProperty(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }) : obj[key] = value, obj;
- }
- __webpack_require__.d(__webpack_exports__, "a", function() {
- return formatAxisMap;
- });
- var __WEBPACK_IMPORTED_MODULE_0__ChartUtils__ = __webpack_require__(16), _extends = Object.assign || function(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]);
- }
- return target;
- }, formatAxisMap = function(props, axisMap, offset, axisType, chartName) {
- var width = props.width, height = props.height, layout = props.layout, ids = Object.keys(axisMap), steps = {
- left: offset.left,
- leftMirror: offset.left,
- right: width - offset.right,
- rightMirror: width - offset.right,
- top: offset.top,
- topMirror: offset.top,
- bottom: height - offset.bottom,
- bottomMirror: height - offset.bottom
- };
- return ids.reduce(function(result, id) {
- var axis = axisMap[id], orientation = axis.orientation, domain = axis.domain, _axis$padding = axis.padding, padding = void 0 === _axis$padding ? {} : _axis$padding, mirror = axis.mirror, reversed = axis.reversed, offsetKey = orientation + (mirror ? "Mirror" : ""), range = void 0, x = void 0, y = void 0, needSpace = void 0;
- range = "xAxis" === axisType ? [ offset.left + (padding.left || 0), offset.left + offset.width - (padding.right || 0) ] : "yAxis" === axisType ? "horizontal" === layout ? [ offset.top + offset.height - (padding.bottom || 0), offset.top + (padding.top || 0) ] : [ offset.top + (padding.top || 0), offset.top + offset.height - (padding.bottom || 0) ] : axis.range,
- reversed && (range = [ range[1], range[0] ]);
- var _parseScale = Object(__WEBPACK_IMPORTED_MODULE_0__ChartUtils__.A)(axis, chartName), scale = _parseScale.scale, realScaleType = _parseScale.realScaleType;
- scale.domain(domain).range(range), Object(__WEBPACK_IMPORTED_MODULE_0__ChartUtils__.c)(scale);
- var ticks = Object(__WEBPACK_IMPORTED_MODULE_0__ChartUtils__.v)(scale, _extends({}, axis, {
- realScaleType: realScaleType
- }));
- "xAxis" === axisType ? (needSpace = "top" === orientation && !mirror || "bottom" === orientation && mirror,
- x = offset.left, y = steps[offsetKey] - needSpace * axis.height) : "yAxis" === axisType && (needSpace = "left" === orientation && !mirror || "right" === orientation && mirror,
- x = steps[offsetKey] - needSpace * axis.width, y = offset.top);
- var finalAxis = _extends({}, axis, ticks, {
- realScaleType: realScaleType,
- x: x,
- y: y,
- scale: scale,
- width: "xAxis" === axisType ? offset.width : axis.width,
- height: "yAxis" === axisType ? offset.height : axis.height
- });
- return finalAxis.bandSize = Object(__WEBPACK_IMPORTED_MODULE_0__ChartUtils__.g)(finalAxis, ticks),
- axis.hide || "xAxis" !== axisType ? axis.hide || (steps[offsetKey] += (needSpace ? -1 : 1) * finalAxis.width) : steps[offsetKey] += (needSpace ? -1 : 1) * finalAxis.height,
- _extends({}, result, _defineProperty({}, id, finalAxis));
- }, {});
- };
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- var emptyObject = {};
- "production" !== process.env.NODE_ENV && Object.freeze(emptyObject), module.exports = emptyObject;
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- var emptyFunction = __webpack_require__(39), warning = emptyFunction;
- if ("production" !== process.env.NODE_ENV) {
- var printWarning = function(format) {
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) args[_key - 1] = arguments[_key];
- var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() {
- return args[argIndex++];
- });
- "undefined" != typeof console && console.error(message);
- try {
- throw new Error(message);
- } catch (x) {}
- };
- warning = function(condition, format) {
- if (void 0 === format) throw new Error("` + "`")) + (`warning(condition, format, ...args)` + ("`" + ` requires a warning message argument");
- if (0 !== format.indexOf("Failed Composite propType: ") && !condition) {
- for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2];
- printWarning.apply(void 0, [ format ].concat(args));
- }
- };
- }
- module.exports = warning;
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- "use strict";
- (function(process) {
- function checkDCE() {
- if ("undefined" != typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" == typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE) {
- if ("production" !== process.env.NODE_ENV) throw new Error("^_^");
- try {
- __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
- } catch (err) {
- console.error(err);
- }
- }
- }
- "production" === process.env.NODE_ENV ? (checkDCE(), module.exports = __webpack_require__(339)) : module.exports = __webpack_require__(342);
- }).call(exports, __webpack_require__(2));
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function is(x, y) {
- return x === y ? 0 !== x || 0 !== y || 1 / x == 1 / y : x !== x && y !== y;
- }
- function shallowEqual(objA, objB) {
- if (is(objA, objB)) return !0;
- if ("object" != typeof objA || null === objA || "object" != typeof objB || null === objB) return !1;
- var keysA = Object.keys(objA), keysB = Object.keys(objB);
- if (keysA.length !== keysB.length) return !1;
- for (var i = 0; i < keysA.length; i++) if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) return !1;
- return !0;
- }
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- module.exports = shallowEqual;
-}, function(module, exports, __webpack_require__) {
- var toInteger = __webpack_require__(137), min = Math.min;
- module.exports = function(it) {
- return it > 0 ? min(toInteger(it), 9007199254740991) : 0;
- };
-}, function(module, exports) {
- var id = 0, px = Math.random();
- module.exports = function(key) {
- return "Symbol(".concat(void 0 === key ? "" : key, ")_", (++id + px).toString(36));
- };
-}, function(module, exports) {
- exports.f = {}.propertyIsEnumerable;
-}, function(module, exports, __webpack_require__) {
- "use strict";
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- exports.__esModule = !0;
- var _iterator = __webpack_require__(357), _iterator2 = _interopRequireDefault(_iterator), _symbol = __webpack_require__(365), _symbol2 = _interopRequireDefault(_symbol), _typeof = "function" == typeof _symbol2.default && "symbol" == typeof _iterator2.default ? function(obj) {
- return typeof obj;
- } : function(obj) {
- return obj && "function" == typeof _symbol2.default && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj;
- };
- exports.default = "function" == typeof _symbol2.default && "symbol" === _typeof(_iterator2.default) ? function(obj) {
- return void 0 === obj ? "undefined" : _typeof(obj);
- } : function(obj) {
- return obj && "function" == typeof _symbol2.default && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : void 0 === obj ? "undefined" : _typeof(obj);
- };
-}, function(module, exports, __webpack_require__) {
- var anObject = __webpack_require__(47), dPs = __webpack_require__(361), enumBugKeys = __webpack_require__(140), IE_PROTO = __webpack_require__(138)("IE_PROTO"), Empty = function() {}, createDict = function() {
- var iframeDocument, iframe = __webpack_require__(207)("iframe"), i = enumBugKeys.length;
- for (iframe.style.display = "none", __webpack_require__(362).appendChild(iframe),
- iframe.src = "javascript:", iframeDocument = iframe.contentWindow.document, iframeDocument.open(),
- iframeDocument.write("
-