@@ -25,6 +25,8 @@ public class AccountProvider extends BasicProvider implements IAccountProvider {
2525private static final int MAX_END_BLOCK =999999999 ;
2626private static final int MIN_START_BLOCK =0 ;
2727
28+ private static final int OFFSET_MAX =10000 ;
29+
2830private static final String BALANCE_ACTION =ACTION_PARAM +"balance" ;
2931private static final String BALANCE_MULTI_ACTION =ACTION_PARAM +"balancemulti" ;
3032private static final String TX_ACTION =ACTION_PARAM +"txlist" ;
@@ -55,11 +57,11 @@ public Balance balance(final String address) {
5557BasicUtils .validateAddress (address );
5658
5759final String urlParams =BALANCE_ACTION +TAG_LATEST_PARAM +ADDRESS_PARAM +address ;
58- final StringResponseTO converted =getRequest (urlParams ,StringResponseTO .class );
59- if (converted .getStatus () !=1 )
60- throw new EtherScanException (converted .getMessage () +", with status " +converted .getStatus ());
60+ final StringResponseTO response =getRequest (urlParams ,StringResponseTO .class );
61+ if (response .getStatus () !=1 )
62+ throw new EtherScanException (response .getMessage () +", with status " +response .getStatus ());
6163
62- return new Balance (address ,Long .valueOf (converted .getResult ()));
64+ return new Balance (address ,Long .valueOf (response .getResult ()));
6365 }
6466
6567@ NotNull
@@ -76,12 +78,12 @@ public List<Balance> balances(final List<String> addresses) {
7678
7779for (final List <String >batch :addressesAsBatches ) {
7880final String urlParams =BALANCE_MULTI_ACTION +TAG_LATEST_PARAM +ADDRESS_PARAM +toAddressParam (batch );
79- final BalanceResponseTO converted =getRequest (urlParams ,BalanceResponseTO .class );
80- if (converted .getStatus () !=1 )
81- throw new EtherScanException (converted .getMessage () +", with status " +converted .getStatus ());
81+ final BalanceResponseTO response =getRequest (urlParams ,BalanceResponseTO .class );
82+ if (response .getStatus () !=1 )
83+ throw new EtherScanException (response .getMessage () +", with status " +response .getStatus ());
8284
83- if (!BasicUtils .isEmpty (converted . getBalances ()))
84- balances .addAll (converted . getBalances ().stream ()
85+ if (!BasicUtils .isEmpty (response . getResult ()))
86+ balances .addAll (response . getResult ().stream ()
8587 .map (Balance ::of )
8688 .collect (Collectors .toList ()));
8789 }
@@ -96,7 +98,6 @@ private String toAddressParam(final List<String> addresses) {
9698@ NotNull
9799@ Override
98100public List <Tx >txs (final String address ) {
99- //TODO all txs implementations with pagination
100101return txs (address ,MIN_START_BLOCK );
101102 }
102103
@@ -111,21 +112,44 @@ public List<Tx> txs(final String address, final long startBlock) {
111112public List <Tx >txs (final String address ,final long startBlock ,final long endBlock ) {
112113BasicUtils .validateAddress (address );
113114
115+ final String offsetParam =PAGE_PARAM +"%s" +OFFSET_PARAM +OFFSET_MAX ;
114116final String blockParam =START_BLOCK_PARAM +startBlock +END_BLOCK_PARAM +endBlock ;
115- final String urlParams =TX_ACTION +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
116- final TxResponseTO converted =getRequest (urlParams ,TxResponseTO .class );
117- if (converted .getStatus () !=1 )
118- throw new EtherScanException (converted .getMessage () +" with status " +converted .getStatus ());
117+ final String urlParams =TX_ACTION +offsetParam +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
119118
120- return (converted .getResult () ==null )
121- ?Collections .emptyList ()
122- :converted .getResult ();
119+ return getRequestUsingOffset (urlParams ,TxResponseTO .class );
120+ }
121+
122+ /**
123+ * Generic search for txs using offset api param
124+ * To avoid 10k limit per response
125+ *
126+ * @param urlParams Url params for #getRequest()
127+ * @param tClass responseListTO class
128+ * @param <T> responseTO list T type
129+ * @param <R> responseListTO type
130+ * @return List of T values
131+ */
132+ private <T ,R extends BaseListResponseTO >List <T >getRequestUsingOffset (final String urlParams ,Class <R >tClass ) {
133+ final List <T >result =new ArrayList <>();
134+ int page =1 ;
135+ while (true ) {
136+ final String formattedUrl =String .format (urlParams ,page ++);
137+ final R response =getRequest (formattedUrl ,tClass );
138+ BasicUtils .validateTxResponse (response );
139+ if (BasicUtils .isEmpty (response .getResult ()))
140+ break ;
141+
142+ result .addAll (response .getResult ());
143+ if (response .getResult ().size () <OFFSET_MAX )
144+ break ;
145+ }
146+
147+ return result ;
123148 }
124149
125150@ NotNull
126151@ Override
127152public List <TxInternal >txsInternal (final String address ) {
128- //TODO all txs implementations with pagination
129153return txsInternal (address ,MIN_START_BLOCK );
130154 }
131155
@@ -140,36 +164,31 @@ public List<TxInternal> txsInternal(final String address, final long startBlock)
140164public List <TxInternal >txsInternal (final String address ,final long startBlock ,final long endBlock ) {
141165BasicUtils .validateAddress (address );
142166
167+ final String offsetParam =PAGE_PARAM +"%s" +OFFSET_PARAM +OFFSET_MAX ;
143168final String blockParam =START_BLOCK_PARAM +startBlock +END_BLOCK_PARAM +endBlock ;
144- final String urlParams =TX_INTERNAL_ACTION +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
145- final TxInternalResponseTO converted =getRequest (urlParams ,TxInternalResponseTO .class );
146- if (converted .getStatus () !=1 )
147- throw new EtherScanException (converted .getMessage () +" with status " +converted .getStatus ());
169+ final String urlParams =TX_INTERNAL_ACTION +offsetParam +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
148170
149- return (converted .getResult () ==null )
150- ?Collections .emptyList ()
151- :converted .getResult ();
171+ return getRequestUsingOffset (urlParams ,TxInternalResponseTO .class );
152172 }
153173
174+
154175@ NotNull
155176@ Override
156177public List <TxInternal >txsInternalByHash (final String txhash ) {
157178BasicUtils .validateTxHash (txhash );
158179
159180final String urlParams =TX_INTERNAL_ACTION +TXHASH_PARAM +txhash ;
160- final TxInternalResponseTO converted =getRequest (urlParams ,TxInternalResponseTO .class );
161- if (converted .getStatus () !=1 )
162- throw new EtherScanException (converted .getMessage () +" with status " +converted .getStatus ());
181+ final TxInternalResponseTO response =getRequest (urlParams ,TxInternalResponseTO .class );
182+ BasicUtils .validateTxResponse (response );
163183
164- return ( converted .getResult () == null )
184+ return BasicUtils . isEmpty ( response .getResult ())
165185 ?Collections .emptyList ()
166- :converted .getResult ();
186+ :response .getResult ();
167187 }
168188
169189@ NotNull
170190@ Override
171191public List <TxToken >txsToken (final String address ) {
172- //TODO all txs implementations with pagination
173192return txsToken (address ,MIN_START_BLOCK );
174193 }
175194
@@ -184,29 +203,21 @@ public List<TxToken> txsToken(final String address, final long startBlock) {
184203public List <TxToken >txsToken (final String address ,final long startBlock ,final long endBlock ) {
185204BasicUtils .validateAddress (address );
186205
206+ final String offsetParam =PAGE_PARAM +"%s" +OFFSET_PARAM +OFFSET_MAX ;
187207final String blockParam =START_BLOCK_PARAM +startBlock +END_BLOCK_PARAM +endBlock ;
188- final String urlParams =TX_TOKEN_ACTION +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
189- final TxTokenResponseTO converted =getRequest (urlParams ,TxTokenResponseTO .class );
190- if (converted .getStatus () !=1 )
191- throw new EtherScanException (converted .getMessage () +" with status " +converted .getStatus ());
208+ final String urlParams =TX_TOKEN_ACTION +offsetParam +ADDRESS_PARAM +address +blockParam +SORT_ASC_PARAM ;
192209
193- return (converted .getResult () ==null )
194- ?Collections .emptyList ()
195- :converted .getResult ();
210+ return getRequestUsingOffset (urlParams ,TxTokenResponseTO .class );
196211 }
197212
198213@ NotNull
199214@ Override
200215public List <Block >minedBlocks (final String address ) {
201216BasicUtils .validateAddress (address );
202217
203- final String urlParams =MINED_ACTION +BLOCK_TYPE_PARAM +ADDRESS_PARAM +address ;
204- final BlockResponseTO converted =getRequest (urlParams ,BlockResponseTO .class );
205- if (converted .getStatus () !=1 )
206- throw new EtherScanException (converted .getMessage () +" with status " +converted .getStatus ());
218+ final String offsetParam =PAGE_PARAM +"%s" +OFFSET_PARAM +OFFSET_MAX ;
219+ final String urlParams =MINED_ACTION +offsetParam +BLOCK_TYPE_PARAM +ADDRESS_PARAM +address ;
207220
208- return (converted .getResult () ==null )
209- ?Collections .emptyList ()
210- :converted .getResult ();
221+ return getRequestUsingOffset (urlParams ,BlockResponseTO .class );
211222 }
212223}