Class: Tapyrus::Validation

Inherits:
Object
  • Object
show all
Defined in:
lib/tapyrus/validation.rb

Instance Method Summary collapse

Instance Method Details

#check_block(block, state) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/tapyrus/validation.rb', line 55

def check_block(block, state)
  # check block header
  return false unless check_block_header(block.header, state)

  # check merkle root

  # size limits

  # first tx is coinbase?

  # check tx count

  # check sigop count
end

#check_block_header(header, state) ⇒ Object

check proof of work



50
51
52
53
# File 'lib/tapyrus/validation.rb', line 50

def check_block_header(header, state)
  header.block_hash
  header.bits
end

#check_tx(tx, state) ⇒ Object

check transaction validation



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/tapyrus/validation.rb', line 4

def check_tx(tx, state)
  # Basic checks that don't depend on any context
  if tx.inputs.empty?
    return state.DoS(10, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-vin-empty")
  end

  if tx.outputs.empty?
    return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-vout-empty")
  end

  # Check for negative or overflow output values
  amount = 0
  tx.outputs.each do |o|
    if o.value < 0
      return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-vout-negative")
    end
    if MAX_MONEY < o.value
      return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-vout-toolarge")
    end
    amount += o.value
    if MAX_MONEY < amount
      return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-vout-toolarge")
    end
  end

  # Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
  out_points = tx.inputs.map { |i| i.out_point.to_payload }
  unless out_points.size == out_points.uniq.size
    return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-inputs-duplicate")
  end

  if tx.coinbase_tx?
    if tx.inputs[0].out_point.index == 0xffffffff || tx.inputs[0].script_sig.size > 100
      return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-cb-length")
    end
  else
    tx.inputs.each do |i|
      if i.out_point.nil? || !i.out_point.valid?
        return state.DoS(10, reject_code: Message::Reject::CODE_INVALID, reject_reason: "bad-txns-prevout-null")
      end
    end
  end
  true
end