gitlab.com/flarenetwork/coreth@v0.1.1/chain/subscribe_block_logs_test.go (about) 1 package chain 2 3 import ( 4 "context" 5 "math/big" 6 "testing" 7 "time" 8 9 "gitlab.com/flarenetwork/coreth/eth/filters" 10 11 "github.com/ethereum/go-ethereum/common" 12 "gitlab.com/flarenetwork/coreth/core/types" 13 ) 14 15 func TestBlockLogsAllowUnfinalized(t *testing.T) { 16 chain, newTxPoolHeadChan, txSubmitCh := NewDefaultChain(t) 17 18 chain.Start() 19 defer chain.Stop() 20 21 acceptedLogsCh := make(chan []*types.Log, 1000) 22 ethBackend := chain.APIBackend() 23 ethBackend.SubscribeAcceptedLogsEvent(acceptedLogsCh) 24 25 api := filters.NewPublicFilterAPI(ethBackend, true, 5*time.Minute) 26 27 // *NOTE* this was pre-compiled for the test.. 28 /* 29 pragma solidity >=0.6.0; 30 31 contract Counter { 32 uint256 x; 33 34 event CounterEmit(uint256 indexed oldval, uint256 indexed newval); 35 36 constructor() public { 37 emit CounterEmit(0, 42); 38 x = 42; 39 } 40 41 function add(uint256 y) public returns (uint256) { 42 x = x + y; 43 emit CounterEmit(y, x); 44 return x; 45 } 46 } 47 */ 48 // contracts, err := compiler.CompileSolidityString("", src) 49 // checkError(err) 50 // contract, _ := contracts[fmt.Sprintf("%s:%s", ".", "Counter")] 51 // _ = contract 52 53 // solc-linux-amd64-v0.6.12+commit.27d51765 --bin -o counter.bin counter.sol 54 55 code := common.Hex2Bytes( 56 "608060405234801561001057600080fd5b50602a60007f53564ba0be98bdbd40460eb78d2387edab91de6a842e1449053dae1f07439a3160405160405180910390a3602a60008190555060e9806100576000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80631003e2d214602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008160005401600081905550600054827f53564ba0be98bdbd40460eb78d2387edab91de6a842e1449053dae1f07439a3160405160405180910390a3600054905091905056fea2646970667358221220dd9c84516cd903bf6a151cbdaef2f2514c28f2f422782a388a2774412b81f08864736f6c634300060c0033", 57 // contract.Code[2:], 58 ) 59 60 tx := types.NewContractCreation(uint64(0), big.NewInt(0), uint64(gasLimit), gasPrice, code) 61 signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), fundedKey.PrivateKey) 62 if err != nil { 63 t.Fatal(err) 64 } 65 for _, err := range chain.AddRemoteTxs([]*types.Transaction{signedTx}) { 66 if err != nil { 67 t.Fatal(err) 68 } 69 } 70 <-txSubmitCh 71 block, err := chain.GenerateBlock() 72 if err != nil { 73 t.Fatal(err) 74 } 75 insertAndSetPreference(t, chain, block) 76 77 <-newTxPoolHeadChan 78 79 if block.NumberU64() != uint64(1) { 80 t.Fatalf("Expected to create a new block with height 1, but found %d", block.NumberU64()) 81 } 82 83 ctx := context.Background() 84 fc := filters.FilterCriteria{ 85 FromBlock: big.NewInt(1), 86 ToBlock: big.NewInt(1), 87 } 88 89 fid, err := api.NewFilter(fc) 90 if err != nil { 91 t.Fatalf("Failed to create NewFilter due to %s", err) 92 } 93 94 chain.BlockChain().GetVMConfig().AllowUnfinalizedQueries = true 95 logs, err := api.GetLogs(ctx, fc) 96 if err != nil { 97 t.Fatalf("GetLogs failed due to %s", err) 98 } 99 if len(logs) != 1 { 100 t.Fatalf("Expected GetLogs to return 1 log, but found %d", len(logs)) 101 } 102 if logs[0].BlockNumber != 1 { 103 t.Fatalf("Expected GetLogs to return 1 log with block number 1, but found block number %d", logs[0].BlockNumber) 104 } 105 106 logs, err = api.GetFilterLogs(ctx, fid) 107 if err != nil { 108 t.Fatalf("GetFilter failed due to %s", err) 109 } 110 if len(logs) != 1 { 111 t.Fatalf("Expected GetFilterLogs to return 1 log, but found %d", len(logs)) 112 } 113 if logs[0].BlockNumber != 1 { 114 t.Fatalf("Expected GetFilterLogs to return 1 log with BlockNumber 1, but found BlockNumber %d", logs[0].BlockNumber) 115 } 116 117 // Fetching blocks from an unfinalized height without specifying a to height 118 // will not yield any logs because the to block is populated using the last 119 // accepted block. 120 fc2 := filters.FilterCriteria{ 121 FromBlock: big.NewInt(1), 122 } 123 124 fid2, err := api.NewFilter(fc2) 125 if err != nil { 126 t.Fatalf("Failed to create NewFilter due to %s", err) 127 } 128 129 logs, err = api.GetLogs(ctx, fc2) 130 if err == nil || err.Error() != "begin block 1 is greater than end block 0" { 131 t.Fatalf("Expected GetLogs to error about invalid range, but found error %s", err) 132 } 133 if len(logs) != 0 { 134 t.Fatalf("Expected GetLogs to return 0 log, but found %d", len(logs)) 135 } 136 137 logs, err = api.GetFilterLogs(ctx, fid2) 138 if err == nil || err.Error() != "begin block 1 is greater than end block 0" { 139 t.Fatalf("Expected GetLogs to error about invalid range, but found error %s", err) 140 } 141 if len(logs) != 0 { 142 t.Fatalf("Expected GetFilterLogs to return 0 log, but found %d", len(logs)) 143 } 144 145 chain.BlockChain().GetVMConfig().AllowUnfinalizedQueries = false 146 logs, err = api.GetLogs(ctx, fc) 147 if logs != nil { 148 t.Fatalf("Expected logs to be empty, but found %d logs", len(logs)) 149 } 150 if err == nil || err.Error() != "requested from block 1 after last accepted block 0" { 151 t.Fatalf("Expected GetLogs to error due to requesting above last accepted block, but found error %s", err) 152 } 153 154 logs, err = api.GetFilterLogs(ctx, fid) 155 if logs != nil { 156 t.Fatalf("Expected GetFilterLogs to return empty logs, but found %d logs", len(logs)) 157 } 158 if err == nil || err.Error() != "requested from block 1 after last accepted block 0" { 159 t.Fatalf("Expected GetLogs to fail due to requesting block above last accepted block, but found error %s", err) 160 } 161 162 logs, err = api.GetLogs(ctx, fc2) 163 if logs != nil { 164 t.Fatalf("Expected logs to be empty, but found %d logs", len(logs)) 165 } 166 if err == nil || err.Error() != "requested from block 1 after last accepted block 0" { 167 t.Fatalf("Expected GetLogs to error due to requesting above last accepted block, but found error %s", err) 168 } 169 170 logs, err = api.GetFilterLogs(ctx, fid2) 171 if logs != nil { 172 t.Fatalf("Expected GetFilterLogs to return empty logs, but found %d logs", len(logs)) 173 } 174 if err == nil || err.Error() != "requested from block 1 after last accepted block 0" { 175 t.Fatalf("Expected GetLogs to fail due to requesting block above last accepted block, but found error %s", err) 176 } 177 178 fc3 := filters.FilterCriteria{ 179 FromBlock: big.NewInt(0), 180 ToBlock: big.NewInt(1), 181 } 182 logs, err = api.GetLogs(ctx, fc3) 183 if logs != nil { 184 t.Fatalf("Expected GetLogs to return empty, but found %d logs", len(logs)) 185 } 186 if err == nil || err.Error() != "requested to block 1 after last accepted block 0" { 187 t.Fatalf("Expected GetLogs to error due to requesting block above last accepted block, but found error %s", err) 188 } 189 190 fid3, err := api.NewFilter(fc3) 191 if err != nil { 192 t.Fatalf("NewFilter failed due to %s", err) 193 } 194 logs, err = api.GetFilterLogs(ctx, fid3) 195 if logs != nil { 196 t.Fatalf("Expected GetFilterLogs to return empty logs but found %d logs", len(logs)) 197 } 198 if err == nil || err.Error() != "requested to block 1 after last accepted block 0" { 199 t.Fatalf("Expected GetFilterLogs to fail due to requesting block above last accepted block, but found error %s", err) 200 } 201 202 // Unless otherwise specified, getting the latest will still return the last 203 // accepted logs even when AllowUnfinalizedQueries = true. 204 fc4 := filters.FilterCriteria{} 205 logs, err = api.GetLogs(ctx, fc4) 206 if err != nil { 207 t.Fatalf("Failed to GetLogs for FilterCriteria with empty from and to block due to %s", err) 208 } 209 if len(logs) != 0 { 210 t.Fatalf("Expected GetLogs to return 0 log, but found %d", len(logs)) 211 } 212 fid4, err := api.NewFilter(fc4) 213 if err != nil { 214 t.Fatalf("NewFilter failed due to %s", err) 215 } 216 logs, err = api.GetFilterLogs(ctx, fid4) 217 if err != nil { 218 t.Fatalf("GetFilterLogs failed due to %s", err) 219 } 220 if len(logs) != 0 { 221 t.Fatalf("Expected GetFilterLogs to return 0 log, but found %d", len(logs)) 222 } 223 224 select { 225 case <-acceptedLogsCh: 226 t.Fatal("Received accepted logs event before Accepting block") 227 default: 228 } 229 230 if err := chain.Accept(block); err != nil { 231 t.Fatal(err) 232 } 233 234 chain.BlockChain().GetVMConfig().AllowUnfinalizedQueries = false 235 logs, err = api.GetLogs(ctx, fc) 236 if err != nil { 237 t.Fatalf("GetLogs failed due to %s", err) 238 } 239 if len(logs) != 1 { 240 t.Fatalf("Expected GetLogs to return 1 log, but found %d", len(logs)) 241 } 242 if logs[0].BlockNumber != 1 { 243 t.Fatalf("Expected single log to have block number 1, but found %d", logs[0].BlockNumber) 244 } 245 246 logs, err = api.GetFilterLogs(ctx, fid) 247 if err != nil { 248 t.Fatalf("GetFilterLogs failed due to %s", err) 249 } 250 if len(logs) != 1 { 251 t.Fatalf("Expected GetFilterLogs to return 1 log, but found %d", len(logs)) 252 } 253 if logs[0].BlockNumber != 1 { 254 t.Fatalf("Expected GetFilterLogs to return 1 log with BlocKNumber 1, but found BlockNumber %d", logs[0].BlockNumber) 255 } 256 257 logs, err = api.GetLogs(ctx, fc4) 258 if err != nil { 259 t.Fatalf("Failed to GetLogs for FilterCriteria with empty from and to block due to %s", err) 260 } 261 if len(logs) != 1 { 262 t.Fatalf("Expected GetLogs to return 1 log, but found %d", len(logs)) 263 } 264 if logs[0].BlockNumber != 1 { 265 t.Fatalf("Expected single log to have block number 1, but found %d", logs[0].BlockNumber) 266 } 267 fid4, err = api.NewFilter(fc4) 268 if err != nil { 269 t.Fatalf("NewFilter failed due to %s", err) 270 } 271 logs, err = api.GetFilterLogs(ctx, fid4) 272 if err != nil { 273 t.Fatalf("GetFilterLogs failed due to %s", err) 274 } 275 if len(logs) != 1 { 276 t.Fatalf("Expected GetFilterLogs to return 1 log, but found %d", len(logs)) 277 } 278 if logs[0].BlockNumber != 1 { 279 t.Fatalf("Expected GetFilterLogs to return 1 log with BlockNumber 1, but found BlockNumber %d", logs[0].BlockNumber) 280 } 281 282 select { 283 case acceptedLogs := <-acceptedLogsCh: 284 if len(acceptedLogs) != 1 { 285 t.Fatalf("Expected accepted logs channel to return 1 log, but found %d", len(acceptedLogs)) 286 } 287 if acceptedLogs[0].BlockNumber != 1 { 288 t.Fatalf("Expected accepted logs channel to return 1 log with BlockNumber 1, but found BlockNumber %d", acceptedLogs[0].BlockNumber) 289 } 290 default: 291 t.Fatal("Failed to receive logs via accepted logs channel") 292 } 293 }