ruby-ethereum 0.9.6 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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