Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/babel/traverse-7.23.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Rubilmax authored Jan 31, 2024
2 parents 3e4f9b3 + dffa3e2 commit 1711e31
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
27 changes: 22 additions & 5 deletions src/multicall-provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import DataLoader from "dataloader";
import { BlockTag, BytesLike, AbstractProvider, PerformActionRequest, Network } from "ethers";
import {
BlockTag,
BytesLike,
AbstractProvider,
PerformActionRequest,
Network,
isHexString,
} from "ethers";

import { multicallAddresses } from "./constants";
import { Multicall2, Multicall3 } from "./types";
Expand Down Expand Up @@ -48,7 +55,8 @@ export class MulticallWrapper {
*/
public static wrap<T extends AbstractProvider>(
provider: T,
maxMulticallDataLength = 0
maxMulticallDataLength = 0,
cache = true
): MulticallProvider<T> {
if (MulticallWrapper.isMulticallProvider(provider)) return provider; // Do not overwrap when given provider is already a multicall provider.

Expand Down Expand Up @@ -157,7 +165,10 @@ export class MulticallWrapper {

return results;
},
{ cacheKeyFn: ({ call }) => (call.to + call.data + call.blockTag.toString()).toLowerCase() }
{
cache,
cacheKeyFn: ({ call }) => (call.to + call.data + call.blockTag.toString()).toLowerCase(),
}
);

// Expose `Provider.fetchNetwork` to fetch & update the network cache when needed
Expand Down Expand Up @@ -199,9 +210,15 @@ export class MulticallWrapper {

if (multicall == null) return _perform(req);

return dataLoader.load({
call: { to, data, blockTag },
const request = {
call: { to, data, blockTag, blockNumber },
multicall,
};

return dataLoader.load(request).then((value) => {
if (blockNumber == null) dataLoader.clear(request);

return value;
});
};

Expand Down
3 changes: 2 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BlockTag, ContractRunner, isHexString } from "ethers";
import { BlockTag, ContractRunner, isHexString, toNumber } from "ethers";

import {
multicall2Address,
Expand All @@ -16,6 +16,7 @@ export enum MulticallVersion {

export const getBlockNumber = (blockTag: BlockTag) => {
if (isHexString(blockTag)) return parseInt(blockTag as string, 16);
else if (typeof blockTag === "bigint") return toNumber(blockTag);
else if (typeof blockTag === "number") return blockTag;
else if (blockTag === "earliest") return 0;

Expand Down
41 changes: 40 additions & 1 deletion test/multicall-provider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as dotenv from "dotenv";
import { JsonRpcProvider, WebSocketProvider, ZeroAddress, ethers } from "ethers";
import {
AbiCoder,
JsonRpcProvider,
WebSocketProvider,
ZeroAddress,
ethers,
toUtf8Bytes,
} from "ethers";
import _range from "lodash/range";

import { multicall3Address, multicall2Address } from "../src/constants";
Expand Down Expand Up @@ -251,5 +258,37 @@ describe("ethers-multicall-provider", () => {

expect(provider.send).toHaveBeenCalledTimes(4);
});

it("should not cache latest request", async () => {
jest
.spyOn(provider, "send")
.mockImplementation(() =>
Promise.resolve(
AbiCoder.defaultAbiCoder().encode(
["(bool, bytes)[]"],
[[[true, AbiCoder.defaultAbiCoder().encode(["string"], ["UNI1"])]]]
)
)
);

const symbol1 = await uni.symbol();

jest
.spyOn(provider, "send")
.mockImplementation(() =>
Promise.resolve(
AbiCoder.defaultAbiCoder().encode(
["(bool, bytes)[]"],
[[[true, AbiCoder.defaultAbiCoder().encode(["string"], ["UNI2"])]]]
)
)
);

const symbol2 = await uni.symbol();

expect(symbol1).toEqual("UNI1");
expect(symbol2).toEqual("UNI2");
expect(provider.send).toHaveBeenCalledTimes(2);
});
});
});

0 comments on commit 1711e31

Please sign in to comment.