ruby-ethereum 0.9.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b148ff5fc474e2b43055a78679a76e13911534ed
4
- data.tar.gz: 8d19a27b24c3e44c6826418c6062d5d5feccc5c4
3
+ metadata.gz: 924077d29477e9f46eb1db5e877d50064b8763f8
4
+ data.tar.gz: 16e19c8bcda8230a4051e97fcd0953175bd103aa
5
5
  SHA512:
6
- metadata.gz: 1bc3e0f52812048175c9e939ae8250f7a8086365970df3779ff0edfdd6a4faf88015c53365b8e72160739455fd5b2b9ea3c806140a2d6d1f6e8c7fbf0a302c39
7
- data.tar.gz: 9e4c2c2a1182e11a4064a59fe4c8d50c6b51a1b5dcbb79d1407200156b919b6c1d4a7589fc7be4e74eea10859199d94301da44788eee470f7f3e5e08eab876c9
6
+ metadata.gz: 916783bdd8651f67a07897cb4fceb5f8cb75ef272aab5b432c3b17c318285861dbb6a369c8f99f4d3a42755166824e5e002cb870bb2e8a257181a1f1080e35c8
7
+ data.tar.gz: 751ab5b00e1e89c318ac77138714acc6df7bc09fad6ea355b2ddbd85da1679603e56c607a05f040b2924cd9f870f53ada872e427ac22ce439eb5db74cf9d7085
@@ -12,17 +12,22 @@ module Ethereum
12
12
  end
13
13
 
14
14
  @contract = {
15
+ fallback_data: nil,
15
16
  constructor_data: nil,
16
17
  function_data: {},
17
18
  event_data: {}
18
19
  }
19
20
 
20
21
  contract_interface.each do |desc|
21
- encode_types = desc['inputs'].map {|e| e['type'] }
22
- signature = desc['inputs'].map {|e| [e['type'], e['name']] }
23
-
24
- # type can be omitted, defaulting to function
25
22
  type = desc['type'] || 'function'
23
+ encode_types = []
24
+ signature = []
25
+
26
+ if type != 'fallback' && desc.has_key?('inputs')
27
+ encode_types = desc['inputs'].map {|e| e['type'] }
28
+ signature = desc['inputs'].map {|e| [e['type'], e['name']] }
29
+ end
30
+
26
31
  case type
27
32
  when 'function'
28
33
  name = basename desc['name']
@@ -32,7 +37,8 @@ module Ethereum
32
37
  encode_types: encode_types,
33
38
  decode_types: decode_types,
34
39
  is_constant: desc.fetch('constant', false),
35
- signature: signature
40
+ signature: signature,
41
+ payable: desc.fetch('payable', false)
36
42
  }
37
43
  when 'event'
38
44
  name = basename desc['name']
@@ -51,6 +57,11 @@ module Ethereum
51
57
  encode_types: encode_types,
52
58
  signature: signature
53
59
  }
60
+ when 'fallback'
61
+ raise ValueError, "Only one fallback function is supported." if @contract[:fallback_data]
62
+ @contract[:fallback_data] = {
63
+ payable: desc['payable']
64
+ }
54
65
  else
55
66
  raise ValueError, "Unknown interface type: #{type}"
56
67
  end
@@ -25,15 +25,15 @@ module Ethereum
25
25
  end
26
26
 
27
27
  def get(k)
28
- logger.trace 'getting entry', key: Utils.encode_hex(k)[0,8]
28
+ logger.debug 'getting entry', key: Utils.encode_hex(k)[0,8]
29
29
 
30
30
  if @uncommited.has_key?(k)
31
31
  raise KeyError, 'key not in db' unless @uncommited[k]
32
- logger.trace "from uncommited"
32
+ logger.debug "from uncommited"
33
33
  return @uncommited[k]
34
34
  end
35
35
 
36
- logger.trace "from db"
36
+ logger.debug "from db"
37
37
  raise KeyError, k.inspect unless @db.exists?(k)
38
38
  v = @db.get(k)
39
39
  o = decompress v
@@ -43,7 +43,7 @@ module Ethereum
43
43
  end
44
44
 
45
45
  def put(k, v)
46
- logger.trace 'putting entry', key: Utils.encode_hex(k)[0,8], size: v.size
46
+ logger.debug 'putting entry', key: Utils.encode_hex(k)[0,8], size: v.size
47
47
  @uncommited[k] = v
48
48
  end
49
49
 
@@ -64,7 +64,7 @@ module Ethereum
64
64
  end
65
65
 
66
66
  def delete(k)
67
- logger.trace 'deleting entry', key: key
67
+ logger.debug 'deleting entry', key: key
68
68
  @uncommited[k] = nil
69
69
  end
70
70
 
@@ -34,14 +34,14 @@ module Ethereum
34
34
  new_refcount = Utils.encode_int(refcount+1)
35
35
  ref_put k, RLP.encode([new_refcount, v])
36
36
 
37
- if Logger.trace?(logger.name)
37
+ if logger.trace?
38
38
  logger.trace "increasing #{Utils.encode_hex(k)}=#{v} to #{refcount+1}"
39
39
  end
40
40
  rescue
41
41
  ref_put k, RLP.encode([ONE_ENCODED, v])
42
42
  @journal.push [ZERO_ENCODED, k]
43
43
 
44
- if Logger.trace?(logger.name)
44
+ if logger.trace?
45
45
  logger.trace "increasing #{Utils.encode_hex(k)}=#{v} to 1"
46
46
  end
47
47
  end
@@ -54,7 +54,7 @@ module Ethereum
54
54
  node_object = RLP.decode ref_get(k)
55
55
  refcount = Utils.decode_int node_object[0]
56
56
 
57
- if Logger.trace?(logger.name)
57
+ if logger.trace?
58
58
  logger.trace "decreasing #{Utils.encode_hex(k)} to #{refcount-1}"
59
59
  end
60
60
 
@@ -61,7 +61,10 @@ module Ethereum
61
61
 
62
62
  dao_fork_blknum: 1920000,
63
63
  child_dao_list: Utils.child_dao_list.map {|addr| Utils.normalize_address addr },
64
- dao_withdrawer: Utils.normalize_address('0xbf4ed7b27f1d666546e30d74d50d173d20bca754')
64
+ dao_withdrawer: Utils.normalize_address('0xbf4ed7b27f1d666546e30d74d50d173d20bca754'),
65
+
66
+ anti_dos_fork_blknum: 2457000,
67
+ clearing_fork_blknum: 2**100
65
68
  }.freeze
66
69
 
67
70
  attr :db, :config, :global_config
@@ -80,6 +80,10 @@ module Ethereum
80
80
  @block.number >= @block.config[:homestead_fork_blknum]
81
81
  end
82
82
 
83
+ def post_anti_dos_hardfork
84
+ @block.number >= @block.config[:anti_dos_fork_blknum]
85
+ end
86
+
83
87
  def post_metropolis_hardfork
84
88
  @block.number >= @block.config[:metropolis_fork_blknum]
85
89
  end
@@ -147,9 +151,13 @@ module Ethereum
147
151
  def apply_msg(msg, code=nil)
148
152
  code ||= get_code msg.code_address
149
153
 
150
- log_msg.debug "MSG APPLY", sender: Utils.encode_hex(msg.sender), to: Utils.encode_hex(msg.to), gas: msg.gas, value: msg.value, data: Utils.encode_hex(msg.data.extract_all)
151
- log_state.trace "MSG PRE STATE SENDER", account: Utils.encode_hex(msg.sender), balance: get_balance(msg.sender), state: log_storage(msg.sender)
152
- log_state.trace "MSG PRE STATE RECIPIENT", account: Utils.encode_hex(msg.to), balance: get_balance(msg.to), state: log_storage(msg.to)
154
+ if log_msg.trace?
155
+ log_msg.debug "MSG APPLY", sender: Utils.encode_hex(msg.sender), to: Utils.encode_hex(msg.to), gas: msg.gas, value: msg.value, data: Utils.encode_hex(msg.data.extract_all)
156
+ if log_state.trace?
157
+ log_state.trace "MSG PRE STATE SENDER", account: Utils.encode_hex(msg.sender), balance: get_balance(msg.sender), state: log_storage(msg.sender)
158
+ log_state.trace "MSG PRE STATE RECIPIENT", account: Utils.encode_hex(msg.to), balance: get_balance(msg.to), state: log_storage(msg.to)
159
+ end
160
+ end
153
161
 
154
162
  # snapshot before execution
155
163
  snapshot = self.snapshot
@@ -169,9 +177,13 @@ module Ethereum
169
177
  res, gas, dat = VM.execute self, msg, code
170
178
  end
171
179
 
172
- log_msg.trace "MSG APPLIED", gas_remained: gas, sender: msg.sender, to: msg.to, data: dat
173
- log_state.trace "MSG POST STATE SENDER", account: Utils.encode_hex(msg.sender), balance: get_balance(msg.sender), state: log_storage(msg.sender)
174
- log_state.trace "MSG POST STATE RECIPIENT", account: Utils.encode_hex(msg.to), balance: get_balance(msg.to), state: log_storage(msg.to)
180
+ if log_msg.trace?
181
+ log_msg.trace "MSG APPLIED", gas_remained: gas, sender: msg.sender, to: msg.to, data: dat
182
+ if log_state.trace?
183
+ log_state.trace "MSG POST STATE SENDER", account: Utils.encode_hex(msg.sender), balance: get_balance(msg.sender), state: log_storage(msg.sender)
184
+ log_state.trace "MSG POST STATE RECIPIENT", account: Utils.encode_hex(msg.to), balance: get_balance(msg.to), state: log_storage(msg.to)
185
+ end
186
+ end
175
187
 
176
188
  if res == 0
177
189
  log_msg.debug 'REVERTING'
@@ -57,7 +57,7 @@ module Ethereum
57
57
  s.gas -= gas
58
58
 
59
59
  ops.each do |op|
60
- if Logger.trace?(log_vm_exit.name)
60
+ if log_vm_exit.trace?
61
61
  trace_data = {
62
62
  stack: s.stack.map(&:to_s),
63
63
  inst: op,
@@ -573,12 +573,16 @@ module Ethereum
573
573
  end
574
574
 
575
575
  def vm_exception(error, **kwargs)
576
- log_vm_exit.trace('EXCEPTION', cause: error, **kwargs)
576
+ if log_vm_exit.trace?
577
+ log_vm_exit.trace('EXCEPTION', cause: error, **kwargs)
578
+ end
577
579
  return 0, 0, []
578
580
  end
579
581
 
580
582
  def peaceful_exit(cause, gas, data, **kwargs)
581
- log_vm_exit.trace('EXIT', cause: cause, **kwargs)
583
+ if log_vm_exit.trace?
584
+ log_vm_exit.trace('EXIT', cause: cause, **kwargs)
585
+ end
582
586
  return 1, gas, data
583
587
  end
584
588
 
@@ -127,5 +127,12 @@ module Ethereum
127
127
  GCALLNEWACCOUNT = 25000
128
128
  GSUICIDEREFUND = 24000
129
129
 
130
+ SLOAD_SUPPLEMENTAL_GAS = 150
131
+ CALL_SUPPLEMENTAL_GAS = 660
132
+ EXTCODELOAD_SUPPLEMENTAL_GAS = 680
133
+ BALANCE_SUPPLEMENTAL_GAS = 380
134
+ CALL_CHILD_LIMIT_NUM = 63
135
+ CALL_CHILD_LIMIT_DENOM = 64
136
+ SUICIDE_SUPPLEMENTAL_GAS = 5000
130
137
  end
131
138
  end
@@ -310,6 +310,8 @@ module Ethereum
310
310
  end
311
311
 
312
312
  def which(cmd)
313
+ return ENV['SOLC_BINARY'] if ENV['SOLC_BINARY']
314
+
313
315
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
314
316
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
315
317
  exts.each { |ext|
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : ascii-8bit -*-
2
2
 
3
3
  module Ethereum
4
- VERSION = '0.9.6'
4
+ VERSION = '0.10.0'
5
5
  end
@@ -33,7 +33,6 @@ module Ethereum
33
33
  steps = 0
34
34
  _prevop = nil
35
35
 
36
- timestamp = Time.now
37
36
  loop do
38
37
  return peaceful_exit('CODE OUT OF RANGE', s.gas, []) if s.pc >= processed_code.size
39
38
 
@@ -50,7 +49,7 @@ module Ethereum
50
49
  # only to decide which features get logged in 'eth.vm.op', i.e.
51
50
  # tracing can not be activated by activating a sub like
52
51
  # 'eth.vm.op.stack'.
53
- if Logger.trace?(log_vm_exit.name)
52
+ if log_vm_exit.trace?
54
53
  trace_data = {
55
54
  stack: s.stack.map(&:to_s),
56
55
  gas: s.gas + fee,
@@ -211,6 +210,9 @@ module Ethereum
211
210
  when :ADDRESS
212
211
  stk.push Utils.coerce_to_int(msg.to)
213
212
  when :BALANCE
213
+ if ext.post_anti_dos_hardfork
214
+ return vm_exception('OUT OF GAS') unless eat_gas(s, Opcodes::BALANCE_SUPPLEMENTAL_GAS)
215
+ end
214
216
  s0 = stk.pop
215
217
  addr = Utils.coerce_addr_to_hex(s0 % 2**160)
216
218
  stk.push ext.get_balance(addr)
@@ -249,10 +251,16 @@ module Ethereum
249
251
  when :GASPRICE
250
252
  stk.push ext.tx_gasprice
251
253
  when :EXTCODESIZE
254
+ if ext.post_anti_dos_hardfork
255
+ return vm_exception('OUT OF GAS') unless eat_gas(s, Opcodes::EXTCODELOAD_SUPPLEMENTAL_GAS)
256
+ end
252
257
  addr = stk.pop
253
258
  addr = Utils.coerce_addr_to_hex(addr % 2**160)
254
259
  stk.push (ext.get_code(addr) || Constant::BYTE_EMPTY).size
255
260
  when :EXTCODECOPY
261
+ if ext.post_anti_dos_hardfork
262
+ return vm_exception('OUT OF GAS') unless eat_gas(s, Opcodes::EXTCODELOAD_SUPPLEMENTAL_GAS)
263
+ end
256
264
  addr, mstart, cstart, size = stk.pop, stk.pop, stk.pop, stk.pop
257
265
  addr = Utils.coerce_addr_to_hex(addr % 2**160)
258
266
  extcode = ext.get_code(addr) || Constant::BYTE_EMPTY
@@ -308,6 +316,9 @@ module Ethereum
308
316
  return vm_exception('OOG EXTENDING MEMORY') unless mem_extend(mem, s, s0, 1)
309
317
  mem[s0] = s1 % 256
310
318
  when :SLOAD
319
+ if ext.post_anti_dos_hardfork
320
+ return vm_exception('OUT OF GAS') unless eat_gas(s, Opcodes::SLOAD_SUPPLEMENTAL_GAS)
321
+ end
311
322
  s0 = stk.pop
312
323
  stk.push ext.get_storage_data(msg.to, s0)
313
324
  when :SSTORE
@@ -385,7 +396,9 @@ module Ethereum
385
396
 
386
397
  data = mem.safe_slice(mstart, msz)
387
398
  ext.log(msg.to, topics, Utils.int_array_to_bytes(data))
388
- log_log.trace('LOG', to: msg.to, topics: topics, data: data)
399
+ if log_log.trace?
400
+ log_log.trace('LOG', to: msg.to, topics: topics, data: data)
401
+ end
389
402
  elsif op == :CREATE
390
403
  value, mstart, msz = stk.pop, stk.pop, stk.pop
391
404
 
@@ -393,15 +406,20 @@ module Ethereum
393
406
 
394
407
  if ext.get_balance(msg.to) >= value && msg.depth < 1024
395
408
  cd = CallData.new mem, mstart, msz
396
- create_msg = Message.new(msg.to, Constant::BYTE_EMPTY, value, s.gas, cd, depth: msg.depth+1)
409
+
410
+ ingas = s.gas
411
+ if ext.post_anti_dos_hardfork
412
+ ingas = max_call_gas(ingas)
413
+ end
414
+ create_msg = Message.new(msg.to, Constant::BYTE_EMPTY, value, ingas, cd, depth: msg.depth+1)
397
415
 
398
416
  o, gas, addr = ext.create create_msg
399
417
  if o.true?
400
418
  stk.push Utils.coerce_to_int(addr)
401
- s.gas = gas
419
+ s.gas -= (ingas - gas)
402
420
  else
403
421
  stk.push 0
404
- s.gas = 0
422
+ s.gas -= ingas
405
423
  end
406
424
  else
407
425
  stk.push(0)
@@ -415,12 +433,17 @@ module Ethereum
415
433
 
416
434
  to = Utils.zpad_int(to)[12..-1] # last 20 bytes
417
435
  extra_gas = (ext.account_exists(to) ? 0 : 1) * Opcodes::GCALLNEWACCOUNT +
418
- (value > 0 ? 1 : 0) * Opcodes::GCALLVALUETRANSFER
436
+ (value > 0 ? 1 : 0) * Opcodes::GCALLVALUETRANSFER +
437
+ (ext.post_anti_dos_hardfork ? 1 : 0) * Opcodes::CALL_SUPPLEMENTAL_GAS
438
+ if ext.post_anti_dos_hardfork
439
+ return vm_exception('OUT OF GAS', needed: extra_gas) if s.gas < extra_gas
440
+ gas = [gas, max_call_gas(s.gas-extra_gas)].min
441
+ else
442
+ return vm_exception('OUT OF GAS', needed: gas+extra_gas) if s.gas < gas+extra_gas
443
+ end
444
+
419
445
  submsg_gas = gas + Opcodes::GSTIPEND * (value > 0 ? 1 : 0)
420
446
  total_gas = gas + extra_gas
421
-
422
- return vm_exception('OUT OF GAS', needed: total_gas) if s.gas < total_gas
423
-
424
447
  if ext.get_balance(msg.to) >= value && msg.depth < 1024
425
448
  s.gas -= total_gas
426
449
 
@@ -454,12 +477,17 @@ module Ethereum
454
477
  return vm_exception('OOG EXTENDING MEMORY') unless mem_extend(mem, s, memin_start, memin_sz)
455
478
  return vm_exception('OOG EXTENDING MEMORY') unless mem_extend(mem, s, memout_start, memout_sz)
456
479
 
457
- extra_gas = (value > 0 ? 1 : 0) * Opcodes::GCALLVALUETRANSFER
480
+ extra_gas = (value > 0 ? 1 : 0) * Opcodes::GCALLVALUETRANSFER +
481
+ (ext.post_anti_dos_hardfork ? 1 : 0) * Opcodes::CALL_SUPPLEMENTAL_GAS
482
+ if ext.post_anti_dos_hardfork
483
+ return vm_exception('OUT OF GAS', needed: extra_gas) if s.gas < extra_gas
484
+ gas = [gas, max_call_gas(s.gas-extra_gas)].min
485
+ else
486
+ return vm_exception('OUT OF GAS', needed: gas+extra_gas) if s.gas < gas+extra_gas
487
+ end
488
+
458
489
  submsg_gas = gas + Opcodes::GSTIPEND * (value > 0 ? 1 : 0)
459
490
  total_gas = gas + extra_gas
460
-
461
- return vm_exception('OUT OF GAS', needed: total_gas) if s.gas < total_gas
462
-
463
491
  if ext.get_balance(msg.to) >= value && msg.depth < 1024
464
492
  s.gas -= total_gas
465
493
 
@@ -496,6 +524,12 @@ module Ethereum
496
524
  s0 = stk.pop
497
525
  to = Utils.zpad_int(s0)[12..-1] # last 20 bytes
498
526
 
527
+ if ext.post_anti_dos_hardfork
528
+ extra_gas = Opcodes::SUICIDE_SUPPLEMENTAL_GAS +
529
+ (ext.account_exists(to) ? 0 : 1) * Opcodes::GCALLNEWACCOUNT
530
+ return vm_exception('OUT OF GAS') unless eat_gas(s, extra_gas)
531
+ end
532
+
499
533
  xfer = ext.get_balance(msg.to)
500
534
  ext.set_balance(to, ext.get_balance(to)+xfer)
501
535
  ext.set_balance(msg.to, 0)
@@ -550,12 +584,16 @@ module Ethereum
550
584
  end
551
585
 
552
586
  def vm_exception(error, **kwargs)
553
- log_vm_exit.trace('EXCEPTION', cause: error, **kwargs)
587
+ if log_vm_exit.trace?
588
+ log_vm_exit.trace('EXCEPTION', cause: error, **kwargs)
589
+ end
554
590
  return 0, 0, []
555
591
  end
556
592
 
557
593
  def peaceful_exit(cause, gas, data, **kwargs)
558
- log_vm_exit.trace('EXIT', cause: cause, **kwargs)
594
+ if log_vm_exit.trace?
595
+ log_vm_exit.trace('EXIT', cause: cause, **kwargs)
596
+ end
559
597
  return 1, gas, data
560
598
  end
561
599
 
@@ -602,5 +640,19 @@ module Ethereum
602
640
  sz * Opcodes::GMEMORY + sz**2 / Opcodes::GQUADRATICMEMDENOM
603
641
  end
604
642
 
643
+ def eat_gas(s, amount)
644
+ if s.gas < amount
645
+ s.gas = 0
646
+ false
647
+ else
648
+ s.gas -= amount
649
+ true
650
+ end
651
+ end
652
+
653
+ def max_call_gas(gas)
654
+ gas - (gas / Opcodes::CALL_CHILD_LIMIT_DENOM)
655
+ end
656
+
605
657
  end
606
658
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-ethereum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Xie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-18 00:00:00.000000000 Z
11
+ date: 2016-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rlp
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: block_logger
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0.1'
103
+ version: 0.1.3
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0.1'
110
+ version: 0.1.3
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: leveldb
113
113
  requirement: !ruby/object:Gem::Requirement